<!DOCTYPE html>
<html lang="en-US" dir="ltr">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>Cookie Session Token⭐ | VitePress</title>
    <meta name="description" content="A VitePress site">
    <link rel="preload stylesheet" href="/notebook/assets/style.3dbfd0c2.css" as="style">
    
    <script type="module" src="/notebook/assets/app.8aaa4cbe.js"></script>
    <link rel="preload" href="/notebook/assets/inter-roman-latin.2ed14f66.woff2" as="font" type="font/woff2" crossorigin="">
    <link rel="modulepreload" href="/notebook/assets/chunks/framework.1336c4e5.js">
    <link rel="modulepreload" href="/notebook/assets/chunks/theme.20cddc0c.js">
    <link rel="modulepreload" href="/notebook/assets/4、微服务_SpringSecurity_进阶篇.md.235a8e9e.lean.js">
    <script id="check-dark-light">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
  </head>
  <body>
    <div id="app"><div class="Layout" data-v-255ec12d><!--[--><!--]--><!--[--><span tabindex="-1" data-v-ae3e3f51></span><a href="#VPContent" class="VPSkipLink visually-hidden" data-v-ae3e3f51> Skip to content </a><!--]--><!----><header class="VPNav" data-v-255ec12d data-v-7e5bc4a5><div class="VPNavBar has-sidebar" data-v-7e5bc4a5 data-v-0937f67c><div class="container" data-v-0937f67c><div class="title" data-v-0937f67c><div class="VPNavBarTitle has-sidebar" data-v-0937f67c data-v-86d1bed8><a class="title" href="/notebook/" data-v-86d1bed8><!--[--><!--]--><!--[--><img class="VPImage logo" src="/notebook/Vue.png" alt data-v-8426fc1a><!--]--><!--[-->任硕的文档<!--]--><!--[--><!--]--></a></div></div><div class="content" data-v-0937f67c><div class="curtain" data-v-0937f67c></div><div class="content-body" data-v-0937f67c><!--[--><!--]--><div class="VPNavBarSearch search" style="--vp-meta-key:&#39;Meta&#39;;" data-v-0937f67c><!--[--><!----><div id="docsearch"><button type="button" class="DocSearch DocSearch-Button" aria-label="Search"><span class="DocSearch-Button-Container"><svg class="DocSearch-Search-Icon" width="20" height="20" viewBox="0 0 20 20" aria-label="search icon"><path d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z" stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"></path></svg><span class="DocSearch-Button-Placeholder">Search</span></span><span class="DocSearch-Button-Keys"><kbd class="DocSearch-Button-Key"></kbd><kbd class="DocSearch-Button-Key">K</kbd></span></button></div><!--]--></div><nav aria-labelledby="main-nav-aria-label" class="VPNavBarMenu menu" data-v-0937f67c data-v-7f418b0f><span id="main-nav-aria-label" class="visually-hidden" data-v-7f418b0f>Main Navigation</span><!--[--><!--[--><div class="VPFlyout VPNavBarMenuGroup" data-v-7f418b0f data-v-a7b5672a><button type="button" class="button" aria-haspopup="true" aria-expanded="false" data-v-a7b5672a><span class="text" data-v-a7b5672a><!----><span data-v-a7b5672a>Java学前端</span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="text-icon" data-v-a7b5672a><path d="M12,16c-0.3,0-0.5-0.1-0.7-0.3l-6-6c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l5.3,5.3l5.3-5.3c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-6,6C12.5,15.9,12.3,16,12,16z"></path></svg></span></button><div class="menu" data-v-a7b5672a><div class="VPMenu" data-v-a7b5672a data-v-e7ea1737><div class="items" data-v-e7ea1737><!--[--><!--[--><div class="VPMenuGroup" data-v-e7ea1737 data-v-69e747b5><!----><!--[--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-2f2cfafc><a class="VPLink link" href="/notebook/Java%E5%AD%A6%E5%89%8D%E7%AB%AF/HTML+JS.html" data-v-2f2cfafc><!--[-->HTML+JS<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-2f2cfafc><a class="VPLink link" href="/notebook/Java%E5%AD%A6%E5%89%8D%E7%AB%AF/CSS.html" data-v-2f2cfafc><!--[-->CSS<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-2f2cfafc><a class="VPLink link" href="/notebook/Java%E5%AD%A6%E5%89%8D%E7%AB%AF/Vue2+%E7%BB%84%E4%BB%B6.html" data-v-2f2cfafc><!--[-->Vue2+组件<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-2f2cfafc><a class="VPLink link" href="/notebook/Java%E5%AD%A6%E5%89%8D%E7%AB%AF/Vue3+%E7%BB%84%E4%BB%B6.html" data-v-2f2cfafc><!--[-->Vue3+组件<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-2f2cfafc><a class="VPLink link" href="/notebook/Java%E5%AD%A6%E5%89%8D%E7%AB%AF/React.html" data-v-2f2cfafc><!--[-->React<!--]--></a></div><!--]--><!--]--></div><!--]--><!--]--></div><!--[--><!--]--></div></div></div><!--]--><!--[--><div class="VPFlyout VPNavBarMenuGroup" data-v-7f418b0f data-v-a7b5672a><button type="button" class="button" aria-haspopup="true" aria-expanded="false" data-v-a7b5672a><span class="text" data-v-a7b5672a><!----><span data-v-a7b5672a>软件测试</span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="text-icon" data-v-a7b5672a><path d="M12,16c-0.3,0-0.5-0.1-0.7-0.3l-6-6c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l5.3,5.3l5.3-5.3c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-6,6C12.5,15.9,12.3,16,12,16z"></path></svg></span></button><div class="menu" data-v-a7b5672a><div class="VPMenu" data-v-a7b5672a data-v-e7ea1737><div class="items" data-v-e7ea1737><!--[--><!--[--><div class="VPMenuGroup" data-v-e7ea1737 data-v-69e747b5><!----><!--[--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-2f2cfafc><a class="VPLink link" href="/notebook/%E8%BD%AF%E4%BB%B6%E6%B5%8B%E8%AF%95/%E6%B5%8B%E8%AF%95%E5%9F%BA%E7%A1%80.html" data-v-2f2cfafc><!--[-->测试基础<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-2f2cfafc><a class="VPLink link" href="/notebook/%E8%BD%AF%E4%BB%B6%E6%B5%8B%E8%AF%95/%E5%8E%8B%E5%8A%9B%E6%B5%8B%E8%AF%95.html" data-v-2f2cfafc><!--[-->压力测试<!--]--></a></div><!--]--><!--]--></div><!--]--><!--]--></div><!--[--><!--]--></div></div></div><!--]--><!--[--><div class="VPFlyout VPNavBarMenuGroup" data-v-7f418b0f data-v-a7b5672a><button type="button" class="button" aria-haspopup="true" aria-expanded="false" data-v-a7b5672a><span class="text" data-v-a7b5672a><!----><span data-v-a7b5672a>多线程</span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="text-icon" data-v-a7b5672a><path d="M12,16c-0.3,0-0.5-0.1-0.7-0.3l-6-6c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l5.3,5.3l5.3-5.3c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-6,6C12.5,15.9,12.3,16,12,16z"></path></svg></span></button><div class="menu" data-v-a7b5672a><div class="VPMenu" data-v-a7b5672a data-v-e7ea1737><div class="items" data-v-e7ea1737><!--[--><!--[--><div class="VPMenuGroup" data-v-e7ea1737 data-v-69e747b5><!----><!--[--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-2f2cfafc><a class="VPLink link" href="/notebook/%E5%B9%B6%E5%8F%91%20&amp;%20%E5%A4%9A%E7%BA%BF%E7%A8%8B/%E5%9F%BA%E7%A1%80%E7%AF%87.html" data-v-2f2cfafc><!--[-->基础篇<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-2f2cfafc><a class="VPLink link" href="/notebook/%E5%B9%B6%E5%8F%91%20&amp;%20%E5%A4%9A%E7%BA%BF%E7%A8%8B/%E5%B9%B6%E5%8F%91%E5%AE%8C%E5%96%84.html" data-v-2f2cfafc><!--[-->进阶篇<!--]--></a></div><!--]--><!--]--></div><!--]--><!--]--></div><!--[--><!--]--></div></div></div><!--]--><!--[--><div class="VPFlyout VPNavBarMenuGroup" data-v-7f418b0f data-v-a7b5672a><button type="button" class="button" aria-haspopup="true" aria-expanded="false" data-v-a7b5672a><span class="text" data-v-a7b5672a><!----><span data-v-a7b5672a>开发工具</span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="text-icon" data-v-a7b5672a><path d="M12,16c-0.3,0-0.5-0.1-0.7-0.3l-6-6c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l5.3,5.3l5.3-5.3c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-6,6C12.5,15.9,12.3,16,12,16z"></path></svg></span></button><div class="menu" data-v-a7b5672a><div class="VPMenu" data-v-a7b5672a data-v-e7ea1737><div class="items" data-v-e7ea1737><!--[--><!--[--><div class="VPMenuGroup" data-v-e7ea1737 data-v-69e747b5><!----><!--[--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-2f2cfafc><a class="VPLink link" href="/notebook/IDEA/Chrome.html" data-v-2f2cfafc><!--[-->Chrome<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-2f2cfafc><a class="VPLink link" href="/notebook/IDEA/IDEA%E5%9F%BA%E7%A1%80.html" data-v-2f2cfafc><!--[-->IDEA基础<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-2f2cfafc><a class="VPLink link" href="/notebook/IDEA/IDEA%E6%8F%92%E4%BB%B6.html" data-v-2f2cfafc><!--[-->IDEA插件<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-2f2cfafc><a class="VPLink link" href="/notebook/IDEA/VS%20Code.html" data-v-2f2cfafc><!--[-->VS Code<!--]--></a></div><!--]--><!--]--></div><!--]--><!--]--></div><!--[--><!--]--></div></div></div><!--]--><!--[--><div class="VPFlyout VPNavBarMenuGroup" data-v-7f418b0f data-v-a7b5672a><button type="button" class="button" aria-haspopup="true" aria-expanded="false" data-v-a7b5672a><span class="text" data-v-a7b5672a><!----><span data-v-a7b5672a>消息中间件</span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="text-icon" data-v-a7b5672a><path d="M12,16c-0.3,0-0.5-0.1-0.7-0.3l-6-6c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l5.3,5.3l5.3-5.3c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-6,6C12.5,15.9,12.3,16,12,16z"></path></svg></span></button><div class="menu" data-v-a7b5672a><div class="VPMenu" data-v-a7b5672a data-v-e7ea1737><div class="items" data-v-e7ea1737><!--[--><!--[--><div class="VPMenuGroup" data-v-e7ea1737 data-v-69e747b5><!----><!--[--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-2f2cfafc><a class="VPLink link" href="/notebook/%E6%B6%88%E6%81%AF%E4%B8%AD%E9%97%B4%E4%BB%B6/RabbitMQ.html" data-v-2f2cfafc><!--[-->RabbitMQ<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-2f2cfafc><a class="VPLink link" href="/notebook/%E6%B6%88%E6%81%AF%E4%B8%AD%E9%97%B4%E4%BB%B6/RocketMQ.html" data-v-2f2cfafc><!--[-->RocketMQ<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-2f2cfafc><a class="VPLink link" href="/notebook/%E6%B6%88%E6%81%AF%E4%B8%AD%E9%97%B4%E4%BB%B6/Kafka.html" data-v-2f2cfafc><!--[-->Kafka<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-2f2cfafc><a class="VPLink link" href="/notebook/%E6%B6%88%E6%81%AF%E4%B8%AD%E9%97%B4%E4%BB%B6/Canal.html" data-v-2f2cfafc><!--[-->Canal<!--]--></a></div><!--]--><!--]--></div><!--]--><!--]--></div><!--[--><!--]--></div></div></div><!--]--><!--]--></nav><!----><div class="VPNavBarAppearance appearance" data-v-0937f67c data-v-f6a63727><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title="toggle dark mode" aria-checked="false" data-v-f6a63727 data-v-82b282f1 data-v-f3c41672><span class="check" data-v-f3c41672><span class="icon" data-v-f3c41672><!--[--><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="sun" data-v-82b282f1><path d="M12,18c-3.3,0-6-2.7-6-6s2.7-6,6-6s6,2.7,6,6S15.3,18,12,18zM12,8c-2.2,0-4,1.8-4,4c0,2.2,1.8,4,4,4c2.2,0,4-1.8,4-4C16,9.8,14.2,8,12,8z"></path><path d="M12,4c-0.6,0-1-0.4-1-1V1c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,3.6,12.6,4,12,4z"></path><path d="M12,24c-0.6,0-1-0.4-1-1v-2c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,23.6,12.6,24,12,24z"></path><path d="M5.6,6.6c-0.3,0-0.5-0.1-0.7-0.3L3.5,4.9c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C6.2,6.5,5.9,6.6,5.6,6.6z"></path><path d="M19.8,20.8c-0.3,0-0.5-0.1-0.7-0.3l-1.4-1.4c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C20.3,20.7,20,20.8,19.8,20.8z"></path><path d="M3,13H1c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S3.6,13,3,13z"></path><path d="M23,13h-2c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S23.6,13,23,13z"></path><path d="M4.2,20.8c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C4.7,20.7,4.5,20.8,4.2,20.8z"></path><path d="M18.4,6.6c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C18.9,6.5,18.6,6.6,18.4,6.6z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="moon" data-v-82b282f1><path d="M12.1,22c-0.3,0-0.6,0-0.9,0c-5.5-0.5-9.5-5.4-9-10.9c0.4-4.8,4.2-8.6,9-9c0.4,0,0.8,0.2,1,0.5c0.2,0.3,0.2,0.8-0.1,1.1c-2,2.7-1.4,6.4,1.3,8.4c2.1,1.6,5,1.6,7.1,0c0.3-0.2,0.7-0.3,1.1-0.1c0.3,0.2,0.5,0.6,0.5,1c-0.2,2.7-1.5,5.1-3.6,6.8C16.6,21.2,14.4,22,12.1,22zM9.3,4.4c-2.9,1-5,3.6-5.2,6.8c-0.4,4.4,2.8,8.3,7.2,8.7c2.1,0.2,4.2-0.4,5.8-1.8c1.1-0.9,1.9-2.1,2.4-3.4c-2.5,0.9-5.3,0.5-7.5-1.1C9.2,11.4,8.1,7.7,9.3,4.4z"></path></svg><!--]--></span></span></button></div><div class="VPSocialLinks VPNavBarSocialLinks social-links" data-v-0937f67c data-v-0394ad82 data-v-7bc22406><!--[--><a class="VPSocialLink no-icon" href="https://github.com/renshuo123/renshuo123.github.io" aria-label="github" target="_blank" rel="noopener" data-v-7bc22406 data-v-f80f8133><svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>GitHub</title><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg></a><a class="VPSocialLink no-icon" href="#" aria-label="twitter" target="_blank" rel="noopener" data-v-7bc22406 data-v-f80f8133><svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Twitter</title><path d="M23.953 4.57a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.69 8.095 4.067 6.13 1.64 3.162a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.06a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.936 4.936 0 004.604 3.417 9.867 9.867 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.053 0 13.998-7.496 13.998-13.985 0-.21 0-.42-.015-.63A9.935 9.935 0 0024 4.59z"/></svg></a><a class="VPSocialLink no-icon" href="https://github.com/" aria-label target="_blank" rel="noopener" data-v-7bc22406 data-v-f80f8133><svg t="1676028692954" class="icon" ...</path></svg></a><!--]--></div><div class="VPFlyout VPNavBarExtra extra" data-v-0937f67c data-v-40855f84 data-v-a7b5672a><button type="button" class="button" aria-haspopup="true" aria-expanded="false" aria-label="extra navigation" data-v-a7b5672a><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="icon" data-v-a7b5672a><circle cx="12" cy="12" r="2"></circle><circle cx="19" cy="12" r="2"></circle><circle cx="5" cy="12" r="2"></circle></svg></button><div class="menu" data-v-a7b5672a><div class="VPMenu" data-v-a7b5672a data-v-e7ea1737><!----><!--[--><!--[--><!----><div class="group" data-v-40855f84><div class="item appearance" data-v-40855f84><p class="label" data-v-40855f84>Appearance</p><div class="appearance-action" data-v-40855f84><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title="toggle dark mode" aria-checked="false" data-v-40855f84 data-v-82b282f1 data-v-f3c41672><span class="check" data-v-f3c41672><span class="icon" data-v-f3c41672><!--[--><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="sun" data-v-82b282f1><path d="M12,18c-3.3,0-6-2.7-6-6s2.7-6,6-6s6,2.7,6,6S15.3,18,12,18zM12,8c-2.2,0-4,1.8-4,4c0,2.2,1.8,4,4,4c2.2,0,4-1.8,4-4C16,9.8,14.2,8,12,8z"></path><path d="M12,4c-0.6,0-1-0.4-1-1V1c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,3.6,12.6,4,12,4z"></path><path d="M12,24c-0.6,0-1-0.4-1-1v-2c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,23.6,12.6,24,12,24z"></path><path d="M5.6,6.6c-0.3,0-0.5-0.1-0.7-0.3L3.5,4.9c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C6.2,6.5,5.9,6.6,5.6,6.6z"></path><path d="M19.8,20.8c-0.3,0-0.5-0.1-0.7-0.3l-1.4-1.4c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C20.3,20.7,20,20.8,19.8,20.8z"></path><path d="M3,13H1c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S3.6,13,3,13z"></path><path d="M23,13h-2c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S23.6,13,23,13z"></path><path d="M4.2,20.8c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C4.7,20.7,4.5,20.8,4.2,20.8z"></path><path d="M18.4,6.6c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C18.9,6.5,18.6,6.6,18.4,6.6z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="moon" data-v-82b282f1><path d="M12.1,22c-0.3,0-0.6,0-0.9,0c-5.5-0.5-9.5-5.4-9-10.9c0.4-4.8,4.2-8.6,9-9c0.4,0,0.8,0.2,1,0.5c0.2,0.3,0.2,0.8-0.1,1.1c-2,2.7-1.4,6.4,1.3,8.4c2.1,1.6,5,1.6,7.1,0c0.3-0.2,0.7-0.3,1.1-0.1c0.3,0.2,0.5,0.6,0.5,1c-0.2,2.7-1.5,5.1-3.6,6.8C16.6,21.2,14.4,22,12.1,22zM9.3,4.4c-2.9,1-5,3.6-5.2,6.8c-0.4,4.4,2.8,8.3,7.2,8.7c2.1,0.2,4.2-0.4,5.8-1.8c1.1-0.9,1.9-2.1,2.4-3.4c-2.5,0.9-5.3,0.5-7.5-1.1C9.2,11.4,8.1,7.7,9.3,4.4z"></path></svg><!--]--></span></span></button></div></div></div><div class="group" data-v-40855f84><div class="item social-links" data-v-40855f84><div class="VPSocialLinks social-links-list" data-v-40855f84 data-v-7bc22406><!--[--><a class="VPSocialLink no-icon" href="https://github.com/renshuo123/renshuo123.github.io" aria-label="github" target="_blank" rel="noopener" data-v-7bc22406 data-v-f80f8133><svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>GitHub</title><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg></a><a class="VPSocialLink no-icon" href="#" aria-label="twitter" target="_blank" rel="noopener" data-v-7bc22406 data-v-f80f8133><svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Twitter</title><path d="M23.953 4.57a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.69 8.095 4.067 6.13 1.64 3.162a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.06a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.936 4.936 0 004.604 3.417 9.867 9.867 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.053 0 13.998-7.496 13.998-13.985 0-.21 0-.42-.015-.63A9.935 9.935 0 0024 4.59z"/></svg></a><a class="VPSocialLink no-icon" href="https://github.com/" aria-label target="_blank" rel="noopener" data-v-7bc22406 data-v-f80f8133><svg t="1676028692954" class="icon" ...</path></svg></a><!--]--></div></div></div><!--]--><!--]--></div></div></div><!--[--><!--]--><button type="button" class="VPNavBarHamburger hamburger" aria-label="mobile navigation" aria-expanded="false" aria-controls="VPNavScreen" data-v-0937f67c data-v-e5dd9c1c><span class="container" data-v-e5dd9c1c><span class="top" data-v-e5dd9c1c></span><span class="middle" data-v-e5dd9c1c></span><span class="bottom" data-v-e5dd9c1c></span></span></button></div></div></div></div><!----></header><div class="VPLocalNav reached-top" data-v-255ec12d data-v-5cfd5582><button class="menu" aria-expanded="false" aria-controls="VPSidebarNav" data-v-5cfd5582><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="menu-icon" data-v-5cfd5582><path d="M17,11H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h14c0.6,0,1,0.4,1,1S17.6,11,17,11z"></path><path d="M21,7H3C2.4,7,2,6.6,2,6s0.4-1,1-1h18c0.6,0,1,0.4,1,1S21.6,7,21,7z"></path><path d="M21,15H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h18c0.6,0,1,0.4,1,1S21.6,15,21,15z"></path><path d="M17,19H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h14c0.6,0,1,0.4,1,1S17.6,19,17,19z"></path></svg><span class="menu-text" data-v-5cfd5582>Menu</span></button><div class="VPLocalNavOutlineDropdown" style="--vp-vh:0px;" data-v-5cfd5582 data-v-18201f51><button data-v-18201f51>Return to top</button><!----></div></div><aside class="VPSidebar" data-v-255ec12d data-v-845b8fc6><div class="curtain" data-v-845b8fc6></div><nav class="nav" id="VPSidebarNav" aria-labelledby="sidebar-aria-label" tabindex="-1" data-v-845b8fc6><span class="visually-hidden" id="sidebar-aria-label" data-v-845b8fc6> Sidebar Navigation </span><!--[--><!--]--><!--[--><div class="group" data-v-845b8fc6><section class="VPSidebarItem level-0 collapsible collapsed" data-v-845b8fc6 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h2 class="text" data-v-9b797284>Java</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/Java/Java%E5%9F%BA%E7%A1%80.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Java基础</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/Java/Java%E6%96%B0%E7%89%B9%E6%80%A7.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Java新特性</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/Java/Java%E8%BF%9B%E9%98%B6.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Java进阶</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/Java/Java%E9%9B%86%E5%90%88.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Java集合</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/Java/Java%E9%AB%98%E7%BA%A7.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Java高级</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-845b8fc6><section class="VPSidebarItem level-0 collapsible collapsed" data-v-845b8fc6 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h2 class="text" data-v-9b797284>Linux</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/Linux/Linux%E5%9F%BA%E7%A1%80.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Linux基础</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/Linux/Linux%E8%BF%9B%E9%98%B6.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Linux新特性</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/Linux/Shell.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Shell脚本</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/Linux/%E5%AE%9E%E7%94%A8%E8%84%9A%E6%9C%AC.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>实用脚本</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/Linux/%E8%BD%AF%E4%BB%B6%E9%83%A8%E7%BD%B2.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>软件部署</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-845b8fc6><section class="VPSidebarItem level-0 collapsible collapsed" data-v-845b8fc6 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h2 class="text" data-v-9b797284>Nginx</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/Nginx/%E5%9F%BA%E7%A1%80%E7%AF%87.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>基础篇</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/Nginx/%E8%BF%9B%E9%98%B6%E7%AF%87.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>进阶篇</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/Nginx/%E5%AE%9E%E6%88%98%E7%AF%87.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>实战篇</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/Nginx/%E9%9D%A2%E8%AF%95%E7%AF%87.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>面试篇</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-845b8fc6><section class="VPSidebarItem level-0 collapsible collapsed" data-v-845b8fc6 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h2 class="text" data-v-9b797284>SSM</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/SSM/Maven.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Maven</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/SSM/Spring.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Spring</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/SSM/SpringMVC.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>SpringMVC</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/SSM/SpringBatch.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>SpringBatch</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-845b8fc6><section class="VPSidebarItem level-0 collapsible collapsed" data-v-845b8fc6 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h2 class="text" data-v-9b797284>SpringBoot</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/3%E3%80%81SpringBoot/%E5%9F%BA%E7%A1%80%E7%AF%87.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>基础篇</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/3%E3%80%81SpringBoot/%E5%BA%94%E7%94%A8%E7%AF%87.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>应用篇</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/3%E3%80%81SpringBoot/%E6%96%B0%E7%89%B9%E6%80%A7.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>新特性</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/3%E3%80%81SpringBoot/%E8%BF%90%E7%BB%B4&amp;%E5%8E%9F%E7%90%86.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>运维&原理</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-845b8fc6><section class="VPSidebarItem level-0 collapsible collapsed" data-v-845b8fc6 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h2 class="text" data-v-9b797284>SpringCloud</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/4%E3%80%81%E5%BE%AE%E6%9C%8D%E5%8A%A1/%E8%BF%9B%E9%98%B6.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>SpringCloud</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/4%E3%80%81%E5%BE%AE%E6%9C%8D%E5%8A%A1/%E5%BF%85%E5%A4%87/Sentinel.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Sentinel</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-845b8fc6><section class="VPSidebarItem level-0 collapsible has-active" data-v-845b8fc6 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h2 class="text" data-v-9b797284>SpringSecurity</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/4%E3%80%81%E5%BE%AE%E6%9C%8D%E5%8A%A1/SpringSecurity/%E5%9F%BA%E7%A1%80%E7%AF%87.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>SpringSecurity基础篇</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/4%E3%80%81%E5%BE%AE%E6%9C%8D%E5%8A%A1/SpringSecurity/%E8%BF%9B%E9%98%B6%E7%AF%87.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>SpringSecurity进阶篇</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/4%E3%80%81%E5%BE%AE%E6%9C%8D%E5%8A%A1/SpringSecurity/%E9%AB%98%E7%BA%A7%E7%AF%87.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>SpringSecurity高级篇</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-845b8fc6><section class="VPSidebarItem level-0 collapsible collapsed" data-v-845b8fc6 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h2 class="text" data-v-9b797284>Mybatis & MybatisPlus</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/Mybatis&amp;MybatisPlus/Mybatis.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Mybatis</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/Mybatis&amp;MybatisPlus/MybatisPlus.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>MybatisPlus</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/Mybatis&amp;MybatisPlus/JPA.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>JPA</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-845b8fc6><section class="VPSidebarItem level-0 collapsible collapsed" data-v-845b8fc6 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h2 class="text" data-v-9b797284>Git & ChatGPT</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/5%E3%80%81%E8%BF%90%E7%BB%B4/Git.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Git</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/5%E3%80%81%E8%BF%90%E7%BB%B4/Github.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Github</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/5%E3%80%81%E8%BF%90%E7%BB%B4/ChatGPT.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>ChatGPT</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/5%E3%80%81%E8%BF%90%E7%BB%B4/Jenkins.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Jenkins</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/5%E3%80%81%E8%BF%90%E7%BB%B4/Netty.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Netty</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-845b8fc6><section class="VPSidebarItem level-0 collapsible collapsed" data-v-845b8fc6 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h2 class="text" data-v-9b797284>数据库</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><section class="VPSidebarItem level-1 collapsible collapsed" data-v-9b797284 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h3 class="text" data-v-9b797284>MySQL</h3><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/2%E3%80%81%E6%95%B0%E6%8D%AE%E5%BA%93/MySQL/MySQL%E6%A0%B8%E5%BF%83/%E5%9F%BA%E7%A1%80.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>MySQL基础</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/2%E3%80%81%E6%95%B0%E6%8D%AE%E5%BA%93/MySQL/MySQL%E6%A0%B8%E5%BF%83/%E8%BF%9B%E9%98%B6.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>MySQL进阶</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/2%E3%80%81%E6%95%B0%E6%8D%AE%E5%BA%93/MySQL/MySQL%E6%A0%B8%E5%BF%83/%E4%BC%98%E5%8C%96.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>MySQL优化</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/2%E3%80%81%E6%95%B0%E6%8D%AE%E5%BA%93/MySQL/MySQL%E6%A0%B8%E5%BF%83/%E8%AE%BE%E8%AE%A1.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>MySQL设计</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/2%E3%80%81%E6%95%B0%E6%8D%AE%E5%BA%93/MySQL/MySQL%E6%A0%B8%E5%BF%83/%E8%BF%90%E7%BB%B4.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>MySQL运维</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/2%E3%80%81%E6%95%B0%E6%8D%AE%E5%BA%93/MySQL/%E5%88%86%E5%BA%93%E5%88%86%E8%A1%A8.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>分库分表</p><!--]--></a><!----></div><!----></div><!--]--></div></section><section class="VPSidebarItem level-1 collapsible collapsed" data-v-9b797284 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h3 class="text" data-v-9b797284>Redis</h3><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/2%E3%80%81%E6%95%B0%E6%8D%AE%E5%BA%93/Redis/Redis%E5%9F%BA%E7%A1%80.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Redis基础</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/2%E3%80%81%E6%95%B0%E6%8D%AE%E5%BA%93/Redis/Redis%E4%BC%98%E5%8C%96.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Redis优化</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/2%E3%80%81%E6%95%B0%E6%8D%AE%E5%BA%93/Redis/Redis%E5%8E%9F%E7%90%86.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Redis原理</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/2%E3%80%81%E6%95%B0%E6%8D%AE%E5%BA%93/Redis/Redis%E9%AB%98%E7%BA%A7.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Redis高级</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/2%E3%80%81%E6%95%B0%E6%8D%AE%E5%BA%93/Redis/Redis%E5%AE%9E%E6%88%98.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Redis实战</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/2%E3%80%81%E6%95%B0%E6%8D%AE%E5%BA%93/Redis/%E6%9C%AC%E5%9C%B0%E7%BC%93%E5%AD%98.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>本地缓存</p><!--]--></a><!----></div><!----></div><!--]--></div></section><section class="VPSidebarItem level-1 collapsible collapsed" data-v-9b797284 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h3 class="text" data-v-9b797284>MongoDB</h3><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/2%E3%80%81%E6%95%B0%E6%8D%AE%E5%BA%93/MongoDB/%E5%9F%BA%E7%A1%80.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>MongoDB基础</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/2%E3%80%81%E6%95%B0%E6%8D%AE%E5%BA%93/MongoDB/%E6%95%B4%E5%90%88.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>MongoDB进阶</p><!--]--></a><!----></div><!----></div><!--]--></div></section><section class="VPSidebarItem level-1 collapsible collapsed" data-v-9b797284 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h3 class="text" data-v-9b797284>ElasticSearch</h3><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/2%E3%80%81%E6%95%B0%E6%8D%AE%E5%BA%93/ElasticSearch/1%E3%80%81ES%E5%9F%BA%E7%A1%80.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>ES基础</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/2%E3%80%81%E6%95%B0%E6%8D%AE%E5%BA%93/ElasticSearch/3%E3%80%81ES%E9%AB%98%E7%BA%A7.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>ES高级</p><!--]--></a><!----></div><!----></div><!--]--></div></section><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/2%E3%80%81%E6%95%B0%E6%8D%AE%E5%BA%93/influxdb.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>InfluxDB</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/2%E3%80%81%E6%95%B0%E6%8D%AE%E5%BA%93/Neo4j.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Neo4j</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-845b8fc6><section class="VPSidebarItem level-0 collapsible collapsed" data-v-845b8fc6 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h2 class="text" data-v-9b797284>高并发 & 秒杀 & 分布式</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E4%B8%89%E9%AB%98/%E5%88%86%E5%B8%83%E5%BC%8F.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>分布式理论</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/4%E3%80%81%E5%BE%AE%E6%9C%8D%E5%8A%A1/%E5%BF%85%E5%A4%87/%E5%88%86%E5%B8%83%E5%BC%8F%E9%94%81.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>分布式锁</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E4%B8%89%E9%AB%98/%E7%A7%92%E6%9D%80.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>秒杀</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E4%B8%89%E9%AB%98/%E9%AB%98%E5%8F%AF%E7%94%A8.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>高可用</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E4%B8%89%E9%AB%98/%E9%AB%98%E5%B9%B6%E5%8F%91.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>高并发</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-845b8fc6><section class="VPSidebarItem level-0 collapsible collapsed" data-v-845b8fc6 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h2 class="text" data-v-9b797284>云原生</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E4%BA%91%E5%8E%9F%E7%94%9F/Docker.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Docker</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E4%BA%91%E5%8E%9F%E7%94%9F/K8S.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>K8S</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-845b8fc6><section class="VPSidebarItem level-0 collapsible collapsed" data-v-845b8fc6 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h2 class="text" data-v-9b797284>可视化 & 监控</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E5%8F%AF%E8%A7%86%E5%8C%96%20&amp;%20%E7%9B%91%E6%8E%A7/%E7%9B%91%E6%8E%A7%E5%9F%BA%E7%A1%80.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>监控基础</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E5%8F%AF%E8%A7%86%E5%8C%96%20&amp;%20%E7%9B%91%E6%8E%A7/%E7%9B%91%E6%8E%A7%E8%BF%9B%E9%98%B6.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>监控进阶</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E5%8F%AF%E8%A7%86%E5%8C%96%20&amp;%20%E7%9B%91%E6%8E%A7/%E5%8F%AF%E8%A7%86%E5%8C%96%E5%A4%A7%E5%B1%8F.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>可视化大屏</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E5%8F%AF%E8%A7%86%E5%8C%96%20&amp;%20%E7%9B%91%E6%8E%A7/Zabbix.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Zabbix</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-845b8fc6><section class="VPSidebarItem level-0 collapsible collapsed" data-v-845b8fc6 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h2 class="text" data-v-9b797284>学前端</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><section class="VPSidebarItem level-1 collapsible collapsed" data-v-9b797284 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h3 class="text" data-v-9b797284>HTML+CSS</h3><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/1%E3%80%81%E5%AD%A6%E5%89%8D%E7%AB%AF/1%E3%80%81HTML+CSS/HTML%E5%9F%BA%E7%A1%80.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>HTML基础</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/1%E3%80%81%E5%AD%A6%E5%89%8D%E7%AB%AF/1%E3%80%81HTML+CSS/CSS%E5%9F%BA%E7%A1%80.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>CSS基础</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/1%E3%80%81%E5%AD%A6%E5%89%8D%E7%AB%AF/1%E3%80%81HTML+CSS/%E7%BD%91%E9%A1%B5%E8%BF%9B%E9%98%B6.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>网页进阶</p><!--]--></a><!----></div><!----></div><!--]--></div></section><section class="VPSidebarItem level-1 collapsible collapsed" data-v-9b797284 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h3 class="text" data-v-9b797284>JS+TS</h3><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/1%E3%80%81%E5%AD%A6%E5%89%8D%E7%AB%AF/2%E3%80%81JS+TS/JS%20%E5%9F%BA%E7%A1%80.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>JS基础</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/1%E3%80%81%E5%AD%A6%E5%89%8D%E7%AB%AF/2%E3%80%81JS+TS/JS%20%E8%BF%9B%E9%98%B6.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>JS进阶</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/1%E3%80%81%E5%AD%A6%E5%89%8D%E7%AB%AF/2%E3%80%81JS+TS/ES6%20%E5%9F%BA%E7%A1%80.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>ES6基础</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/1%E3%80%81%E5%AD%A6%E5%89%8D%E7%AB%AF/2%E3%80%81JS+TS/ES6%20%E8%BF%9B%E9%98%B6.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>ES6进阶</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/1%E3%80%81%E5%AD%A6%E5%89%8D%E7%AB%AF/2%E3%80%81JS+TS/TypeScript.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>TS基础</p><!--]--></a><!----></div><!----></div><!--]--></div></section><section class="VPSidebarItem level-1 collapsible collapsed" data-v-9b797284 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h3 class="text" data-v-9b797284>NodeJS</h3><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/1%E3%80%81%E5%AD%A6%E5%89%8D%E7%AB%AF/4%E3%80%81Node/%E5%9F%BA%E7%A1%80%E7%AF%87.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Node基础</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/1%E3%80%81%E5%AD%A6%E5%89%8D%E7%AB%AF/4%E3%80%81Node/%E8%BF%9B%E9%98%B6%E7%AF%87.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Node进阶</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/1%E3%80%81%E5%AD%A6%E5%89%8D%E7%AB%AF/4%E3%80%81Node/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>项目实战</p><!--]--></a><!----></div><!----></div><!--]--></div></section><section class="VPSidebarItem level-1 collapsible collapsed" data-v-9b797284 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h3 class="text" data-v-9b797284>Vue</h3><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/1%E3%80%81%E5%AD%A6%E5%89%8D%E7%AB%AF/3%E3%80%81Vue/Vue3/Vue3%E8%BF%9B%E9%98%B6.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Vue3进阶</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/1%E3%80%81%E5%AD%A6%E5%89%8D%E7%AB%AF/3%E3%80%81Vue/Vue3/Vue3%E9%AB%98%E7%BA%A7.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Vue3高级</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/1%E3%80%81%E5%AD%A6%E5%89%8D%E7%AB%AF/3%E3%80%81Vue/Vue3/Vue3%E6%96%B0%E8%AF%AD%E6%B3%95.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Vue3新语法</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/1%E3%80%81%E5%AD%A6%E5%89%8D%E7%AB%AF/3%E3%80%81Vue/Vue2/Vue2%E9%A1%B9%E7%9B%AE.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>项目实战</p><!--]--></a><!----></div><!----></div><!--]--></div></section><section class="VPSidebarItem level-1 collapsible collapsed" data-v-9b797284 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h3 class="text" data-v-9b797284>小程序</h3><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/1%E3%80%81%E5%AD%A6%E5%89%8D%E7%AB%AF/5%E3%80%81%E5%B0%8F%E7%A8%8B%E5%BA%8F/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>小程序基础</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/1%E3%80%81%E5%AD%A6%E5%89%8D%E7%AB%AF/5%E3%80%81%E5%B0%8F%E7%A8%8B%E5%BA%8F/%E5%B0%8F%E7%A8%8B%E5%BA%8F%E4%BC%98%E5%8C%96.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>小程序优化</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/1%E3%80%81%E5%AD%A6%E5%89%8D%E7%AB%AF/5%E3%80%81%E5%B0%8F%E7%A8%8B%E5%BA%8F/uniapp.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>uniapp</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/1%E3%80%81%E5%AD%A6%E5%89%8D%E7%AB%AF/5%E3%80%81%E5%B0%8F%E7%A8%8B%E5%BA%8F/%E5%B0%8F%E7%A8%8B%E5%BA%8F%E9%A1%B9%E7%9B%AE.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>项目实战</p><!--]--></a><!----></div><!----></div><!--]--></div></section><!--]--></div></section></div><div class="group" data-v-845b8fc6><section class="VPSidebarItem level-0 collapsible collapsed" data-v-845b8fc6 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h2 class="text" data-v-9b797284>计算机基础</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%9F%BA%E7%A1%80/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E5%9F%BA%E7%A1%80%E7%AF%87.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>数据结构</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%9F%BA%E7%A1%80/%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%9F%BA%E7%A1%80/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>操作系统</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%9F%BA%E7%A1%80/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E5%9F%BA%E7%A1%80%E7%AF%87.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>设计模式</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%9F%BA%E7%A1%80/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E7%BD%91%E7%BB%9C%E5%9F%BA%E7%A1%80.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>计算机网络</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%9F%BA%E7%A1%80/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/UML.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>UML</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%9F%BA%E7%A1%80/%E7%AE%97%E6%B3%95/LeetCode.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>LeetCode</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-845b8fc6><section class="VPSidebarItem level-0 collapsible collapsed" data-v-845b8fc6 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h2 class="text" data-v-9b797284>项目实战</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><section class="VPSidebarItem level-1 collapsible collapsed" data-v-9b797284 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h3 class="text" data-v-9b797284>云尚办公</h3><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98/%E4%BA%91%E5%B0%9A%E5%8A%9E%E5%85%AC/%E5%9F%BA%E7%A1%80%E7%AF%87.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>基础篇</p><!--]--></a><!----></div><!----></div><!--]--></div></section><section class="VPSidebarItem level-1 collapsible collapsed" data-v-9b797284 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h3 class="text" data-v-9b797284>小兔鲜</h3><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98/%E5%B0%8F%E5%85%94%E9%B2%9C/%E5%9F%BA%E7%A1%80%E7%AF%87.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>基础篇</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98/%E5%B0%8F%E5%85%94%E9%B2%9C/%E8%BF%9B%E9%98%B6%E7%AF%871.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>进阶篇1</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98/%E5%B0%8F%E5%85%94%E9%B2%9C/%E8%BF%9B%E9%98%B6%E7%AF%872.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>进阶篇2</p><!--]--></a><!----></div><!----></div><!--]--></div></section><section class="VPSidebarItem level-1 collapsible collapsed" data-v-9b797284 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h3 class="text" data-v-9b797284>地图</h3><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98/%E7%99%BE%E5%BA%A6%E5%9C%B0%E5%9B%BE/%E5%9F%BA%E7%A1%80%E7%AF%87.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>基础篇</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98/%E7%99%BE%E5%BA%A6%E5%9C%B0%E5%9B%BE/%E8%BF%9B%E9%98%B6%E7%AF%87.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>进阶篇</p><!--]--></a><!----></div><!----></div><!--]--></div></section><section class="VPSidebarItem level-1 collapsible collapsed" data-v-9b797284 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h3 class="text" data-v-9b797284>苍穹外卖</h3><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98/%E8%8B%8D%E7%A9%B9%E5%A4%96%E5%8D%96/%E8%BF%9B%E9%98%B6%E7%AF%87.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>进阶篇</p><!--]--></a><!----></div><!----></div><!--]--></div></section><section class="VPSidebarItem level-1 collapsible collapsed" data-v-9b797284 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h3 class="text" data-v-9b797284>黑马头条</h3><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98/%E9%BB%91%E9%A9%AC%E5%A4%B4%E6%9D%A1/%E5%9F%BA%E7%A1%80%E7%AF%87.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>基础篇</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98/%E9%BB%91%E9%A9%AC%E5%A4%B4%E6%9D%A1/%E8%BF%9B%E9%98%B6%E7%AF%87.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>进阶篇</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98/%E9%BB%91%E9%A9%AC%E5%A4%B4%E6%9D%A1/%E8%BF%9B%E9%98%B6%E7%AF%872.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>进阶篇2</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98/%E9%BB%91%E9%A9%AC%E5%A4%B4%E6%9D%A1/%E9%AB%98%E7%BA%A7%E7%AF%87.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>高级篇</p><!--]--></a><!----></div><!----></div><!--]--></div></section><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98/%E6%94%AF%E4%BB%98.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>支付</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98/%E9%A1%B9%E7%9B%AE%E6%8E%A8%E8%8D%90.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>项目推荐</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-845b8fc6><section class="VPSidebarItem level-0" data-v-845b8fc6 data-v-9b797284><!----><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/team.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>团队成员</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><!--]--><!--[--><!--]--></nav></aside><div class="VPContent has-sidebar" id="VPContent" data-v-255ec12d data-v-669faec9><div class="VPDoc has-sidebar has-aside" data-v-669faec9 data-v-6b87e69f><!--[--><!--]--><div class="container" data-v-6b87e69f><div class="aside" data-v-6b87e69f><div class="aside-curtain" data-v-6b87e69f></div><div class="aside-container" data-v-6b87e69f><div class="aside-content" data-v-6b87e69f><div class="VPDocAside" data-v-6b87e69f data-v-3f215769><!--[--><!--]--><!--[--><!--]--><div class="VPDocAsideOutline" data-v-3f215769 data-v-ff0f39c8><div class="content" data-v-ff0f39c8><div class="outline-marker" data-v-ff0f39c8></div><div class="outline-title" data-v-ff0f39c8>On this page</div><nav aria-labelledby="doc-outline-aria-label" data-v-ff0f39c8><span class="visually-hidden" id="doc-outline-aria-label" data-v-ff0f39c8> Table of Contents for current page </span><ul class="root" data-v-ff0f39c8 data-v-d0ee3533><!--[--><!--]--></ul></nav></div></div><!--[--><!--]--><div class="spacer" data-v-3f215769></div><!--[--><!--]--><!----><!--[--><!--]--><!--[--><!--]--></div></div></div></div><div class="content" data-v-6b87e69f><div class="content-container" data-v-6b87e69f><!--[--><!--]--><!----><main class="main" data-v-6b87e69f><div style="position:relative;" class="vp-doc _notebook_4%E3%80%81%E5%BE%AE%E6%9C%8D%E5%8A%A1_SpringSecurity_%E8%BF%9B%E9%98%B6%E7%AF%87" data-v-6b87e69f><div><h1 id="cookie-session-token⭐" tabindex="-1">Cookie Session Token⭐ <a class="header-anchor" href="#cookie-session-token⭐" aria-label="Permalink to &quot;Cookie Session Token⭐&quot;">​</a></h1><h2 id="cookie" tabindex="-1">cookie <a class="header-anchor" href="#cookie" aria-label="Permalink to &quot;cookie&quot;">​</a></h2><blockquote><p>Cookie 总是保存在客户端中，按在客户端中的存储位置，可分为内存 Cookie 和硬盘 Cookie。内存 Cookie 由浏览器维护，保存在内存中，浏览器关闭后就消失了，其存在时间是短暂的；硬盘 Cookie 保存在硬盘里，有一个过期时间，除非用户手工清理或到了过期时间，硬盘 Cookie 不会被删除，其存在时间是长期的。</p></blockquote><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2022.8.30/202208211025424.png" alt="image-20220821102531322" style="zoom:67%;"><h3 id="cookie-定义和作用" tabindex="-1">cookie 定义和作用 <a class="header-anchor" href="#cookie-定义和作用" aria-label="Permalink to &quot;cookie 定义和作用&quot;">​</a></h3><p>HTTP Cookie（也叫 Web Cookie 或浏览器 Cookie）是服务器发送到用户浏览器并保存在本地的一小块数据，它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。</p><p>通常 Cookie 用于告知服务端两个请求是否来自同一浏览器，如保持用户的登录状态。Cookie 使基于无状态的 HTTP 协议记录稳定的状态信息成为了可能。</p><p>Cookie 主要用于以下三个方面：</p><ul><li><p>会话状态管理（如用户登录状态、购物车等其它需要记录的信息）；</p></li><li><p>个性化设置（如用户自定义设置、主题等）；</p></li><li><p>浏览器行为跟踪（如跟踪分析用户行为等）。</p></li><li><p><code>cookie</code> 最开始被设计出来是为了弥补HTTP在状态管理上的不足。</p></li><li><p><code>cookie 存储在客户端</code>：cookie 是服务器发送到用户浏览器并保存在本地的一小块数据，它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。</p></li><li><p><code>cookie 是不可跨域的</code>：每个 cookie 都会绑定单一的域名（包括子域），无法在别的域名下获取使用。</p></li></ul><h3 id="服务端创建-cookie" tabindex="-1">服务端创建 cookie <a class="header-anchor" href="#服务端创建-cookie" aria-label="Permalink to &quot;服务端创建 cookie&quot;">​</a></h3><p>当服务器收到 HTTP 请求时，服务器可以在响应头里面添加一个 Set-Cookie 选项。</p><p>浏览器收到响应后通常会保存下 Cookie，之后对该服务器每一次请求都通过 Cookie 请求头部将 Cookie 信息发送给服务器。另外，Cookie 的过期时间、域、路径、有效期、适用站点都可以根据需要来指定。</p><p>服务器向客户端发送 Cookie 是通过 HTTP 响应报文实现的，在 Set-Cookie 中设置需要向客户端发送的cookie，cookie格式如下：</p><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2022.8.30/202208211027110.png" alt="image-20220821102758971" style="zoom:67%;"><p>服务器使用 Set-Cookie 响应头部向用户浏览器发送 Cookie 信息。</p><p>一个简单的 Cookie 可能像这样：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">Set-Cookie: &lt;cookie名&gt;=&lt;cookie值&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;"></span></span>
<span class="line"><span style="color:#A6ACCD;">HTTP/1.0 200 OK</span></span>
<span class="line"><span style="color:#A6ACCD;">Content-type: text/html</span></span>
<span class="line"><span style="color:#A6ACCD;">Set-Cookie: yummy_cookie=choco</span></span>
<span class="line"><span style="color:#A6ACCD;">Set-Cookie: tasty_cookie=strawberry</span></span></code></pre></div><p>客户端对该服务器发起的每一次新请求，浏览器都会将之前保存的 Cookie 信息通过 Cookie 请求头部再发送给服务器。</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">GET /sample_page.html HTTP/1.1</span></span>
<span class="line"><span style="color:#A6ACCD;">Host: www.example.org</span></span>
<span class="line"><span style="color:#A6ACCD;">Cookie: yummy_cookie=choco; tasty_cookie=strawberry</span></span></code></pre></div><p>我来访问下淘宝网，抓个包看看这个真实的过程：</p><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2022.8.30/202208211031214.png" alt="image-20220821103140075" style="zoom:67%;"><h3 id="cookie-工作流程" tabindex="-1">cookie 工作流程 <a class="header-anchor" href="#cookie-工作流程" aria-label="Permalink to &quot;cookie 工作流程&quot;">​</a></h3><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2022.6.30/202207212313196.png" alt="image-20220721231310105" style="zoom:67%;"><p>（1）浏览器向服务器发送请求；</p><p>（2）服务器响应请求，向浏览器设置 cookie；</p><p>（3）浏览器将 cookie 存在本地，下一次请求带上该 cookie；</p><p>（4）服务器响应请求。</p><h3 id="存在问题" tabindex="-1">存在问题 <a class="header-anchor" href="#存在问题" aria-label="Permalink to &quot;存在问题&quot;">​</a></h3><p>Cookie 常用来标记用户或授权会话，被浏览器发出之后可能被劫持，被用于非法行为，可能导致授权用户的会话受到攻击，因此存在安全问题。</p><p>还有一种情况就是跨站请求伪造 CSRF，简单来说，比如你在登录银行网站的同时，登录了一个钓鱼网站，在钓鱼网站进行某些操作时可能会获取银行网站相关的 Cookie 信息，向银行网站发起转账等非法行为。</p><blockquote><p>跨站请求伪造（英语：Cross-site request forgery），也被称为 one-click attack 或者 session riding，通常缩写为 CSRF 或者 XSRF， 是一种挟制用户在当前已登录的 Web 应用程序上执行非本意的操作的攻击方法。</p><p>跨站请求攻击（XSS），简单地说，是攻击者通过一些技术手段欺骗用户的浏览器去访问一个自己曾经认证过的网站并运行一些操作（如发邮件、发消息，甚至财产操作如转账和购买商品）。由于浏览器曾经认证过，所以被访问的网站会认为是真正的用户操作而去运行。这利用了 web 中用户身份验证的一个漏洞：简单的身份验证只能保证请求发自某个用户的浏览器，却不能保证请求本身是用户自愿发出的。</p><p>与跨网站脚本（XSS）相比，XSS 利用的是用户对指定网站的信任，CSRF 利用的是网站对用户网页浏览器的信任。</p></blockquote><p>不过这种情况有很多解决方法，特别对于银行这类金融性质的站点，用户的任何敏感操作都需要确认，并且敏感信息的 Cookie 只能拥有较短的生命周期。</p><p>同时 Cookie 有容量和数量的限制，每次都要发送很多信息带来额外的流量消耗、复杂的行为 Cookie 无法满足要求。</p><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2022.8.30/202208211033978.png" alt="image-20220821103333873" style="zoom:67%;"><p>特别注意：以上存在的问题只是 Cookie 被用于实现交互状态时存在的问题，但并不是说 Cookie 本身的问题。试想一下：菜刀可以用来做菜，也可以被用来从事某些暴力行为，你能说菜刀应该被废除吗？</p><h2 id="session" tabindex="-1">Session <a class="header-anchor" href="#session" aria-label="Permalink to &quot;Session&quot;">​</a></h2><h3 id="session机制概念" tabindex="-1">session机制概念 <a class="header-anchor" href="#session机制概念" aria-label="Permalink to &quot;session机制概念&quot;">​</a></h3><blockquote><p>如果说 Cookie 是客户端行为，那么 Session 就是服务端行为。session 翻译过来就是『会话』。用户打开一个浏览器, 点击多个超链接, 访问服务器多个web资源, 然后关闭浏览器, 整个过程称之为一个会话。</p></blockquote><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2022.8.30/202208211035682.png" alt="image-20220821103544551" style="zoom:67%;"><blockquote><p>Cookie 机制在最初和服务端完成交互后，保持状态所需的信息都将存储在客户端，后续直接读取发送给服务端进行交互。</p></blockquote><blockquote><p>Session 代表服务器与浏览器的一次会话过程，并且完全由服务端掌控，实现分配 ID、会话信息存储、会话检索等功能。Session 机制将用户的所有活动信息、上下文信息、登录信息等都存储在服务端，只是生成一个唯一标识 ID 发送给客户端，后续的交互将没有重复的用户信息传输，取而代之的是唯一标识 ID，暂且称之为 Session-ID 吧。</p></blockquote><h3 id="简单的交互流程" tabindex="-1">简单的交互流程 <a class="header-anchor" href="#简单的交互流程" aria-label="Permalink to &quot;简单的交互流程&quot;">​</a></h3><blockquote><p>当客户端第一次请求 session 对象时候，服务器会为客户端创建一个 session，并将通过特殊算法算出一个 session 的 ID，用来标识该 session 对象。</p></blockquote><blockquote><p>当浏览器下次请求别的资源的时候，浏览器会将 sessionID 放置到请求头中，服务器接收到请求后解析得到 sessionID，服务器找到该 id 的 session 来确定请求方的身份和一些上下文信息。</p></blockquote><h3 id="session实现方式" tabindex="-1">Session实现方式 <a class="header-anchor" href="#session实现方式" aria-label="Permalink to &quot;Session实现方式&quot;">​</a></h3><blockquote><p>首先明确一点，Session 和 Cookie 没有直接的关系，可以认为 Cookie 只是实现 Session 机制的一种方法途径而已，没有 Cookie 还可以用别的方法。</p></blockquote><blockquote><p>Session 和 Cookie 的关系就像加班和加班费的关系，看似关系很密切，实际上没啥关系。</p></blockquote><blockquote><p>session 的实现主要两种方式：cookie 与 url 重写，而 cookie 是首选方式，因为各种现代浏览器都默认开通 cookie 功能，但是每种浏览器也都有允许 cookie 失效的设置，因此对于 Session 机制来说还需要一个备胎</p></blockquote><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2022.8.30/202208211041900.png" alt="image-20220821104106779" style="zoom:67%;"><p>将会话标识号以参数形式附加在超链接 URL 地址后面的技术称为 URL 重写。</p><div class="language-c"><button title="Copy Code" class="copy"></button><span class="lang">c</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">//原始的 URL：</span></span>
<span class="line"><span style="color:#A6ACCD;">http:</span><span style="color:#676E95;font-style:italic;">//taobao.com/getitem?name=baymax&amp;action=buy</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">//重写后的 URL:</span></span>
<span class="line"><span style="color:#A6ACCD;">http:</span><span style="color:#676E95;font-style:italic;">//taobao.com/getitem?sessionid=1wui87htentg&amp;?name=baymax&amp;action=buy</span></span></code></pre></div><h3 id="存在的问题" tabindex="-1">存在的问题 <a class="header-anchor" href="#存在的问题" aria-label="Permalink to &quot;存在的问题&quot;">​</a></h3><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2022.8.30/202208211054636.png" alt="image-20220821105451523" style="zoom:67%;"><blockquote><p>由于 Session 信息是存储在服务端的，因此如果用户量很大的场景，Session 信息占用的空间就不容忽视。对于大型网站必然是集群化&amp;分布式的服务器配置，如果 Session 信息是存储在本地的，那么由于负载均衡的作用，原来请求机器 A 并且存储了 Session 信息，下一次请求可能到了机器 B，此时机器 B 上并没有 Session 信息。</p></blockquote><blockquote><p>这种情况下要么在 B 机器重复创建造成浪费，要么引入高可用的 Session 集群方案，引入 Session 代理实现信息共享，要么实现定制化哈希到集群 A，这样做其实就有些复杂了。</p></blockquote><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2022.8.30/202208211055534.png" alt="image-20220821105541412" style="zoom:67%;"><h2 id="token" tabindex="-1">token <a class="header-anchor" href="#token" aria-label="Permalink to &quot;token&quot;">​</a></h2><blockquote><p>Token 是令牌的意思，由服务端生成并发放给客户端，是一种具有时效性的验证身份的手段。Token 避免了 Session 机制带来的海量信息存储问题，也避免了 Cookie 机制的一些安全性问题，在现代移动互联网、跨域访问等场景有广泛的用途。</p></blockquote><h3 id="交互流程" tabindex="-1">交互流程 <a class="header-anchor" href="#交互流程" aria-label="Permalink to &quot;交互流程&quot;">​</a></h3><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2022.8.30/202208211057174.png" alt="image-20220821105733052" style="zoom:67%;"><blockquote><ul><li>客户端将用户的账号和密码提交给服务器</li><li>服务器对其进行校验，通过则生成一个 token 值返回给客户端，作为后续的请求交互身份令牌</li><li>客户端拿到服务端返回的 token 值后，可将其保存在本地，以后每次请求服务器时都携带该 token，提交给服务器进行身份校验；</li><li>服务器接收到请求后，解析关键信息，再根据相同的加密算法、密钥、用户参数生成 sign 与客户端的 sign 进行对比，一致则通过，否则拒绝服务；</li><li>验证通过之后，服务端就可以根据该 Token 中的 uid 获取对应的用户信息，进行业务请求的响应</li></ul></blockquote><h3 id="token-设计思想" tabindex="-1">Token 设计思想 <a class="header-anchor" href="#token-设计思想" aria-label="Permalink to &quot;Token 设计思想&quot;">​</a></h3><p>以 JSON Web Token（JWT）为例，Token 主要由 3 部分组成：</p><ul><li>Header 头部信息 记录了使用的加密算法信息；</li><li>Payload 净荷信息 记录了用户信息和过期时间等；</li><li>Signature 签名信息 根据 header 中的加密算法和 payload 中的用户信息以及密钥 key 来生成，是验证服务端的重要依据。</li></ul><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2022.8.30/202208211144131.png" alt="image-20220821114449004" style="zoom:67%;"><p>header 和 payload 的信息不做加密，只做一般的 base64 编码，服务端收到 token 后，剥离出 header 和 payload 获取算法、用户、过期时间等信息，然后根据自己的加密密钥来生成 sign，并与客户端传来的 sign 进行一致性对比，来确定客户端的身份合法性。</p><p>这样就实现了用 CPU 加解密的时间换取存储空间，同时服务端密钥的重要性就显而易见，一旦泄露整个机制就崩塌了，这个时候就需要考虑 HTTPS 了。</p><h3 id="token-方案的特点" tabindex="-1">Token 方案的特点 <a class="header-anchor" href="#token-方案的特点" aria-label="Permalink to &quot;Token 方案的特点&quot;">​</a></h3><ul><li>Token 可以跨站共享，实现单点登录；</li><li>Token 机制无需太多存储空间，Token 包含了用户的信息，只需在客户端存储状态信息即可，对于服务端的扩展性很好；</li><li>Token 机制的安全性依赖于服务端加密算法和密钥的安全性；</li><li>Token 机制也不是万金油。</li></ul><p>在分布式微服务技术日趋流行的今天，大型网站的设计都尽量避免使用 session 实现 HTTP 状态化。</p><blockquote><p>session简单粗暴，在服务端维护会话信息，在客户端保存session id，服务端能够轻易地把会话控制在自己的手中，但服务集群化产生了session共享的负担；</p></blockquote><blockquote><p>jwt（token）只在客户端保存会话信息，服务端通过密钥校验会话，（相比session）拿时间换空间，卸下了服务端集群共享会话信息的负担，同时也加大了服务端控制会话的难度。</p></blockquote><blockquote><p>Cookie、Session、Token 这三者是不同发展阶段的产物，并且各有优缺点，三者也没有明显的对立关系，反而常常结伴出现，这也是容易被混淆的原因。</p></blockquote><blockquote><p>Cookie 侧重于信息的存储，主要是客户端行为，Session 和 Token 侧重于身份验证，主要是服务端行为。三者方案在很多场景都还有生命力，了解场景才能选择合适的方案，没有银弹。</p></blockquote><h2 id="session和cookie的区别" tabindex="-1">Session和Cookie的区别 <a class="header-anchor" href="#session和cookie的区别" aria-label="Permalink to &quot;Session和Cookie的区别&quot;">​</a></h2><p><strong>我们先来看Session和Cookie的概念吧：</strong></p><p>Cookie是保存在<code>客户端</code>的一小块文本串的数据。客户端向服务器发起请求时，服务端会向客户端发送一个Cookie，客户端就把Cookie保存起来。在客户端下次向同一服务器再发起请求时，Cookie被携带发送到服务器。服务器就是根据这个Cookie来确认身份的。</p><p>Session指的就是<code>服务器和客户端一次会话的过程</code>。Session利用Cookie进行信息处理的，当用户首先进行了请求后，服务端就在用户浏览器上创建了一个Cookie，当这个Session结束时，其实就是意味着这个Cookie就过期了。Session对象存储着特定用户会话所需的属性及配置信息。</p><p><strong>Session 和Cookie的区别主要有这些：</strong></p><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2022.6.23/202206301021500.png" alt="image-20220630102127439" style="zoom:80%;"><p>来看个图吧：</p><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2022.6.23/202206301021584.png" alt="image-20220630102156512" style="zoom:67%;"><blockquote><ul><li>用户第一次请求服务器时，服务器根据用户提交的信息，创建对应的Session，请求返回时将此Session的唯一标识信息SessionID返回给浏览器，浏览器接收到服务器返回的SessionID信息后，会将此信息存入Cookie中，同时Cookie记录此SessionID是属于哪个域名。</li><li>当用户第二次访问服务器时，请求会自动判断此域名下是否存在Cookie信息，如果存在，则自动将Cookie信息也发送给服务端，服务端会从Cookie中获取SessionID，再根据 SessionID查找对应的 Session信息，如果没有找到，说明用户没有登录或者登录失效，如果找到Session证明用户已经登录可执行后面操作。</li></ul></blockquote><h2 id="cookie-session-token详解" tabindex="-1">Cookie Session Token详解 <a class="header-anchor" href="#cookie-session-token详解" aria-label="Permalink to &quot;Cookie Session Token详解&quot;">​</a></h2><p><a href="https://mp.weixin.qq.com/s?__biz=Mzg3NzU5NTIwNg==&amp;mid=2247496583&amp;idx=1&amp;sn=d2de2aaf82aa4e96107f9653d9ec3aca&amp;chksm=cf222caef855a5b8f6a6fbed93ae8cb6fdc127e5664703d2db44da7870a5af1040cb413ed800&amp;mpshare=1&amp;scene=23&amp;srcid=07206xvYjBz0dNuEgejopy6o&amp;sharer_sharetime=1658329065447&amp;sharer_shareid=29b8a04db1dbd975e3bf4e9f47e7ac67#rd" target="_blank" rel="noreferrer">熬夜彻底搞懂Cookie Session Token JWT </a></p><p><a href="https://mp.weixin.qq.com/s?__biz=MzI1MzYzMTI2Ng==&amp;mid=2247486329&amp;idx=1&amp;sn=d20114c694a65069002769a70792d73d&amp;chksm=e9d0c534dea74c223234c68022afdd30189baaa498204522d45ed971ae38a78cf390949bc42b&amp;mpshare=1&amp;scene=23&amp;srcid=1208oaQ6uBX8r6jmSyScAtkO&amp;sharer_sharetime=1670430263727&amp;sharer_shareid=29b8a04db1dbd975e3bf4e9f47e7ac67#rd" target="_blank" rel="noreferrer">聊聊Cookie、Session、Token背后的故事</a></p><blockquote><p><strong>一切的根源就是因为 HTTP 是一个无状态的协议。</strong></p></blockquote><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2022.12.30/202212101139045.png" alt="image-20221210113932884" style="zoom:50%;"><p>网站交互体验升级</p><p>作为网友的我们，每天都会使用浏览器来逛各种网站，来满足日常的工作生活需求。</p><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2022.12.30/202212101141578.png" alt="image-20221210114158414" style="zoom:50%;"><p>现在的交互体验还是很丝滑的，但早期并非如此，而是一锤子买卖。</p><h4 id="http-是一个无状态的协议" tabindex="-1">HTTP 是一个无状态的协议 <a class="header-anchor" href="#http-是一个无状态的协议" aria-label="Permalink to &quot;HTTP 是一个无状态的协议&quot;">​</a></h4><p>无状态的http协议是什么鬼？</p><p>HTTP无状态协议，是指协议对于业务处理没有记忆能力，之前做了啥完全记不住，每次请求都是完全独立互不影响的，没有任何上下文信息。</p><p>缺少状态意味着如果后续处理需要前面的信息，则它必须重传关键信息，这样可能导致每次连接传送的数据量增大。</p><p>如果大家没明白，可以想一下《夏洛特烦恼》里面的桥段：</p><blockquote><p>夏洛：大爷，楼上322住的是马冬梅家吗？ 大爷：马冬什么？ 夏洛：马冬梅。 大爷：什么冬梅啊？ 夏洛：马冬梅啊。 大爷：马什么梅啊？ 夏洛：……行，大爷，您先凉快吧。</p></blockquote><p>「打岔」大爷记不住马冬梅，就如同 HTTP 协议记不住上一次请求。说得通俗一点：HTTP 的记忆力不太好，需要借助『助听器』。</p><p>记忆力不好的优点就是一个字「快」；缺点也很明显，需要借靠 <code>cookie</code>、<code>session</code> 、<code>token</code>等机制将客户端多次请求关联起来。</p><p>大概明白了吧，假如一直用这种原生无状态的 http 协议，我们每换一个页面可能就得重新登录一次，那还玩个球。</p><p>所以必须要解决 http 协议的无状态，提升网站的交互体验，否则星辰大海是去不了的。</p><p>在讲解<code>cookie</code>、<code>session</code> 、<code>token</code>前我们先简单讲解两个概念：<code>认证</code>、<code>授权</code>。</p><h4 id="解决之道" tabindex="-1">解决之道 <a class="header-anchor" href="#解决之道" aria-label="Permalink to &quot;解决之道&quot;">​</a></h4><p>整个事情交互的双方只有客户端和服务端，所以必然要在这两个当事者身上下手。</p><p><strong>客户端来买单</strong></p><blockquote><p>客户端每次请求时把自己必要的信息封装发送给服务端，服务端查收处理一下就行。</p></blockquote><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2022.12.30/202212101146445.png" alt="image-20221210114646299" style="zoom:67%;"><p><strong>服务端来买单</strong></p><blockquote><p>客户端第一次请求之后，服务端就开始做记录，然后客户端在后续请求中只需要将最基本最少的信息发过来就行，不需要太多信息了。</p></blockquote><p><img src="https://mmbiz.qpic.cn/mmbiz_png/wAkAIFs11qaeduHjZ3hQO8VLRdhqqNIPGprPjMan9JGLHFJclbVuuGXMcQC2icDEycBnH3d4zd8r0eMhsOxtb5w/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><h4 id="认证和授权" tabindex="-1">认证和授权 <a class="header-anchor" href="#认证和授权" aria-label="Permalink to &quot;认证和授权&quot;">​</a></h4><h5 id="什么是认证" tabindex="-1">什么是认证 <a class="header-anchor" href="#什么是认证" aria-label="Permalink to &quot;什么是认证&quot;">​</a></h5><p>认证（Authentication）简单来讲就是<strong>验证当前者的身份</strong>，证明<code>你是你自己</code>。</p><p>最常见的认证方式是通过<code>用户名</code>和<code>密码</code>，除此之外还有：</p><ul><li>通过用户手机：手机短信、手机二维码扫描、手势密码</li><li>用户的电子邮箱</li><li>身份证号码</li><li>基于时间序列和用户相关的一次性口令</li><li>用户的生物学特征：指纹、语音、眼睛虹膜等</li></ul><p>为了确认用户的身份，防止请求伪造，在安全要求高的场合，经常会使用组合认证（也叫多因素认证），也就是同时使用多个认证方式对用户的身份进行校验。</p><h5 id="什么是授权" tabindex="-1">什么是授权 <a class="header-anchor" href="#什么是授权" aria-label="Permalink to &quot;什么是授权&quot;">​</a></h5><p>授权（Authorization）简单来讲就是<code>授予第三方访问用户资源的权限</code>。</p><p>在互联网应用开发中，主要通过下面几种方式实现授权：</p><ul><li>通过 session 机制，<code>一个访问会话保持着用户的授权信息</code></li><li>通过 cookie 机制，<code>一个网站的 cookie 保持着用户的授权信息</code></li><li>颁发授权令牌（token），<code>一个合法有效的令牌中保持着用户的授权信息</code></li></ul><h2 id="分布式session" tabindex="-1">分布式session <a class="header-anchor" href="#分布式session" aria-label="Permalink to &quot;分布式session&quot;">​</a></h2><h3 id="问题分析" tabindex="-1">问题分析 <a class="header-anchor" href="#问题分析" aria-label="Permalink to &quot;问题分析&quot;">​</a></h3><p>这种机制在单体应用时代应用非常广泛，但是，随着分布式时代的到来，Session 的缺点也逐渐暴露出来。</p><p>举个例子，比如我们有多个服务器，客户端 1 向服务器发送了一个请求，由于负载均衡的存在，该请求被转发给了服务器 A，于是服务器 A 创建并存储了这个 Session</p><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2022.6.23/202206281541856.png" alt="image-20220628154112778" style="zoom:67%;"><p>紧接着，客户端 1 又向服务器发送了一个请求，但是这一次请求被负载均衡给了服务器 B，而服务器 B 这时候是没有存储服务器 A 的 Session 的，这就导致 Session 的失效。</p><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2022.6.23/202206281541882.png" alt="image-20220628154138811" style="zoom:67%;"><p>明明用户在上一个界面还是登录的，跳到下一个界面就退出登录了，这显然不合理。</p><p>当然了，对此的解决方法其实也有很多种，其实就是如何解决 Session 在多个服务器之间的共享问题：</p><h3 id="session-replication" tabindex="-1">Session Replication <a class="header-anchor" href="#session-replication" aria-label="Permalink to &quot;Session Replication&quot;">​</a></h3><p>这个是最容易想到的，既然服务器 B 没有服务器 A 存储的 Session，那各个服务器之间同步一下 Session 数据不就完了。</p><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2022.6.23/202206281542247.png" alt="image-20220628154208178" style="zoom:67%;"><p>这种方案存在的问题也是显而易见的：</p><ol><li>同步 Session 数据带来了额外的网络带宽开销。只要 Session 数据有变化，就需要将数据同步到所有其他机器上，机器越多，同步带来的网络带宽开销就越大。</li><li>每台Web服务器都要保存所有 Session 数据，如果整个集群的 Session 数据很多（比如很多人同时访问网站的情况），每台服务器用于保存 Session 数据的内存占用会非常严重。</li></ol><h3 id="session-sticky" tabindex="-1">Session Sticky <a class="header-anchor" href="#session-sticky" aria-label="Permalink to &quot;Session Sticky&quot;">​</a></h3><p>从名称也能看出来，Sticky，<code>即让负载均衡器能够根据每次的请求的会话标识来进行请求的转发，保证一个会话中的每次请求都能落到同一台服务器上面。</code></p><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2022.6.23/202206281542723.png" alt="image-20220628154235645" style="zoom:67%;"><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2022.6.23/202206281542591.png" alt="image-20220628154255520" style="zoom:67%;"><p>存在问题的：</p><ol><li><code>如果某台服务器宕机或者重启了，那么它上面存储的 Session 数据就丢失了，用户就需要重新进行登陆。</code></li><li><code>负载均衡器变为一个有状态的节点，因为他需要保存 Session 到具体服务器的映射，和之前无状态的节点相比，内存消耗会更大，容灾方面会更麻烦。</code></li></ol><h3 id="session-数据集中存储" tabindex="-1">Session 数据集中存储 <a class="header-anchor" href="#session-数据集中存储" aria-label="Permalink to &quot;Session 数据集中存储&quot;">​</a></h3><p>借助外部存储（Redis、MySQL 等），将 Session 数据进行集中存储，然后所有的服务器都从这个外部存储中拿 Session</p><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2022.8.30/202208102243833.png" alt="image-20220628162224868" style="zoom:67%;"><p>存在的问题也很显然：</p><ul><li>过度依赖外部存储，如果集中存储 Session 的外部存储机器出问题了，就会直接影响到我们的应用</li></ul><h3 id="threadlocal-推荐" tabindex="-1">ThreadLocal(推荐) <a class="header-anchor" href="#threadlocal-推荐" aria-label="Permalink to &quot;ThreadLocal(推荐)&quot;">​</a></h3><p>事实上，无论采用何种方案，使用 Session 机制，会使得服务器集群很难扩展，因此，Session 适用于中小型 Web 应用程序。对于大型 Web 应用程序来说，通常需要避免使用 Session 机制。</p><p>So，在 Echo 项目中，我们决定摒弃 Session，一个 ThreadLocal 解决所有问题（狗头）！</p><p>ThreadLocal 线程本地内存，很好理解，就是每个访问 ThreadLocal 变量的线程都有自己的一个 “本地” 实例副本，每个线程之间互相隔离，互不干涉。</p><p>这里我就不详细解释底层原理了，ThreadLocal 适用于如下两种场景：</p><blockquote><ul><li>每个线程需要有自己单独的实例（数据）</li><li>实例（数据）需要在多个方法中共享，但不希望被多线程共享</li></ul></blockquote><p>来看如何用 ThreadLocal 实现我们的需求：显示登录信息，在本次请求中持有当前用户数据。</p><p>首先我们需要明白的是，ThreadLocal 只跟其归属的线程有关，线程死亡了，那么它对应的 ThreadLocal 中存储的信息也就被清除了（线程死亡前一定要释放掉绑定的用户数据，不然会出现 OOM 问题），也就是说，ThreadLocal 只用于在本次请求中持有数据。</p><p>简单来说，我们把用户数据存入 <code>ThreadLocal</code> 里，这样，只要本次请求未处理完，这个线程就一直还在，当前用户数据就一直被持有，当服务器对本次请求做出响应后，这个线程就会被销毁。</p><p><code>那同一个用户发出的两次请求可能被不同的两个线程进行处理，如何使得这个两个线程的 ThreadLocal 持有相同的用户信息呢？</code></p><p>答案：过滤器。</p><blockquote><p>具体来说，我们定义一个过滤器，在每次请求前都对用户进行判断（为了避免每次请求都经过过滤器，可以将登录成功的用户信息暂时存储到 Redis 中），然后将已经登录成功的用户信息存到 ThreadLocal 里，从而使得该线程在本次请求中持有该用户信息。</p></blockquote><h1 id="token-1" tabindex="-1">token <a class="header-anchor" href="#token-1" aria-label="Permalink to &quot;token&quot;">​</a></h1><h2 id="生成token" tabindex="-1">生成token <a class="header-anchor" href="#生成token" aria-label="Permalink to &quot;生成token&quot;">​</a></h2><h3 id="实体类" tabindex="-1">实体类 <a class="header-anchor" href="#实体类" aria-label="Permalink to &quot;实体类&quot;">​</a></h3><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Data</span></span>
<span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">NoArgsConstructor</span></span>
<span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">AllArgsConstructor</span></span>
<span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">User</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">implements</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">Serializable</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Integer</span><span style="color:#A6ACCD;"> id</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> username</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> password</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><h3 id="java-jwt" tabindex="-1">java-jwt <a class="header-anchor" href="#java-jwt" aria-label="Permalink to &quot;java-jwt&quot;">​</a></h3><div class="language-xml"><button title="Copy Code" class="copy"></button><span class="lang">xml</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">&lt;!-- https://mvnrepository.com/artifact/com.auth0/java-jwt --&gt;</span></span>
<span class="line"><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">com.auth0</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">java-jwt</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">version</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">4.4.0</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">version</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span></code></pre></div><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Slf4j</span></span>
<span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">JWTUtil</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 设置有效时间和签名密钥</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">long</span><span style="color:#A6ACCD;"> tokenExpiration </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">365</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">*</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">24</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">*</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">60</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">*</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">60</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">*</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1000</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">final</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> TOKEN_SECRET </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">123456</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 生成token，自定义过期时间 毫秒</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">generateToken</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">User</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">user</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">ObjectMapper</span><span style="color:#A6ACCD;"> mapper </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">ObjectMapper</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">try</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">            </span><span style="color:#676E95;font-style:italic;">// 私钥和加密算法</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#C792EA;">Algorithm</span><span style="color:#A6ACCD;"> algorithm </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> Algorithm</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">HMAC256</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">TOKEN_SECRET</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#89DDFF;">            </span><span style="color:#676E95;font-style:italic;">// 设置头部信息</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#C792EA;">Map</span><span style="color:#89DDFF;">&lt;</span><span style="color:#C792EA;">String</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Object</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> header </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">HashMap</span><span style="color:#89DDFF;">&lt;&gt;(</span><span style="color:#F78C6C;">2</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">            header</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">put</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">Type</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">Jwt</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">            header</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">put</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">alg</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">HS256</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> JWT</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">create</span><span style="color:#89DDFF;">()</span></span>
<span class="line"><span style="color:#A6ACCD;">                    </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">withHeader</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">header</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">                    </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">withClaim</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">token</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> mapper</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">writeValueAsString</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">user</span><span style="color:#89DDFF;">))</span></span>
<span class="line"><span style="color:#A6ACCD;">                    </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">withExpiresAt</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;font-style:italic;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">Date</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">System</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">currentTimeMillis</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">+</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#A6ACCD;">                                            tokenExpiration</span><span style="color:#89DDFF;">))</span></span>
<span class="line"><span style="color:#A6ACCD;">                    </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">sign</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">algorithm</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">catch</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">Exception</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">e</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">            log</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">error</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">生成token失败，失败的原因是:{}</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> e</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">null;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 检验token是否正确</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">User</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">parseToken</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">token</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">try</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#C792EA;">ObjectMapper</span><span style="color:#A6ACCD;"> mapper </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">ObjectMapper</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#C792EA;">Algorithm</span><span style="color:#A6ACCD;"> algorithm </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> Algorithm</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">HMAC256</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">TOKEN_SECRET</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#C792EA;">JWTVerifier</span><span style="color:#A6ACCD;"> verifier </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> JWT</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">require</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">algorithm</span><span style="color:#89DDFF;">).</span><span style="color:#82AAFF;">build</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#C792EA;">DecodedJWT</span><span style="color:#A6ACCD;"> jwt </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> verifier</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">verify</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">token</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> tokenInfo </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> jwt</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getClaim</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">token</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">).</span><span style="color:#82AAFF;">asString</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> mapper</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">readValue</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">tokenInfo</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> User</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">class</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">catch</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">JsonProcessingException</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">e</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">            log</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">error</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">token已经过期</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">null;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">void</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">main</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">String</span><span style="color:#89DDFF;">[]</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">args</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">// 生成token</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> token </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">generateToken</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;font-style:italic;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">User</span><span style="color:#89DDFF;">(</span><span style="color:#F78C6C;">1</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">renshuo</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">123456</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">));</span></span>
<span class="line"><span style="color:#A6ACCD;">        System</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">out</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">println</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">token</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">// 验证token</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">User</span><span style="color:#A6ACCD;"> user </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">parseToken</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">token</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">        System</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">out</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">println</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">user</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2023.3.30/202305212159176.png" alt="image-20230521215933124" style="zoom:80%;"><h3 id="jjwt" tabindex="-1">jjwt <a class="header-anchor" href="#jjwt" aria-label="Permalink to &quot;jjwt&quot;">​</a></h3><div class="language-xml"><button title="Copy Code" class="copy"></button><span class="lang">xml</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">io.jsonwebtoken</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">jjwt</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">version</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">0.9.1</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">version</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span></code></pre></div><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">JwtHelper</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 设置有效时间和签名密钥</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">long</span><span style="color:#A6ACCD;"> tokenExpiration </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">365</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">*</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">24</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">*</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">60</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">*</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">60</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">*</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1000</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> tokenSignKey </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">123456</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 根据用户ID和用户名称生成token字符串</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">createToken</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">Long</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">userId</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">username</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> token </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> Jwts</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">builder</span><span style="color:#89DDFF;">()</span></span>
<span class="line"><span style="color:#A6ACCD;">                </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setSubject</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">AUTH-USER</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">// 分类</span></span>
<span class="line"><span style="color:#89DDFF;">                </span><span style="color:#676E95;font-style:italic;">// 设置token有效时长</span></span>
<span class="line"><span style="color:#A6ACCD;">                </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setExpiration</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;font-style:italic;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">Date</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">System</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">currentTimeMillis</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">+</span><span style="color:#A6ACCD;"> tokenExpiration</span><span style="color:#89DDFF;">))</span></span>
<span class="line"><span style="color:#89DDFF;">                </span><span style="color:#676E95;font-style:italic;">// 设置主体</span></span>
<span class="line"><span style="color:#A6ACCD;">                </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">claim</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">userId</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> userId</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">                </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">claim</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">username</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> username</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">                </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">signWith</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">SignatureAlgorithm</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">HS512</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> tokenSignKey</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">                </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">compressWith</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">CompressionCodecs</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">GZIP</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">                </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">compact</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> token</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 从生成的token中获取用户ID</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Long</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">getUserId</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">token</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">try</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">StringUtils</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">isEmpty</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">token</span><span style="color:#89DDFF;">))</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">null;</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#C792EA;">Jws</span><span style="color:#89DDFF;">&lt;</span><span style="color:#C792EA;">Claims</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> claimsJws </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> Jwts</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">parser</span><span style="color:#89DDFF;">().</span><span style="color:#82AAFF;">setSigningKey</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">tokenSignKey</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">                                        </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">parseClaimsJws</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">token</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#C792EA;">Claims</span><span style="color:#A6ACCD;"> claims </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> claimsJws</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getBody</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#C792EA;">Integer</span><span style="color:#A6ACCD;"> userId </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">Integer</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> claims</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">get</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">userId</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> userId</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">longValue</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">catch</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">Exception</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">e</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">            e</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">printStackTrace</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">null;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 从生成的token中获取用户名称</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">getUsername</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">token</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">try</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">StringUtils</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">isEmpty</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">token</span><span style="color:#89DDFF;">))</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;&quot;</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#C792EA;">Jws</span><span style="color:#89DDFF;">&lt;</span><span style="color:#C792EA;">Claims</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> claimsJws </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> Jwts</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">parser</span><span style="color:#89DDFF;">().</span><span style="color:#82AAFF;">setSigningKey</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">tokenSignKey</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">                    </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">parseClaimsJws</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">token</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#C792EA;">Claims</span><span style="color:#A6ACCD;"> claims </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> claimsJws</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getBody</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">String</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> claims</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">get</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">username</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">catch</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">Exception</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">e</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">            e</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">printStackTrace</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">null;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 测试</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">void</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">main</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">String</span><span style="color:#89DDFF;">[]</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">args</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> token </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> JwtHelper</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">createToken</span><span style="color:#89DDFF;">(</span><span style="color:#F78C6C;">1L</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">admin</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">        System</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">out</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">println</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">token</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">        System</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">out</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">println</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">JwtHelper</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getUserId</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">token</span><span style="color:#89DDFF;">));</span></span>
<span class="line"><span style="color:#A6ACCD;">        System</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">out</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">println</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">JwtHelper</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getUsername</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">token</span><span style="color:#89DDFF;">));</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><h1 id="登录实战⭐" tabindex="-1">登录实战⭐ <a class="header-anchor" href="#登录实战⭐" aria-label="Permalink to &quot;登录实战⭐&quot;">​</a></h1><h2 id="基础准备" tabindex="-1">基础准备 <a class="header-anchor" href="#基础准备" aria-label="Permalink to &quot;基础准备&quot;">​</a></h2><h3 id="数据库表" tabindex="-1">数据库表 <a class="header-anchor" href="#数据库表" aria-label="Permalink to &quot;数据库表&quot;">​</a></h3><div class="language-sql"><button title="Copy Code" class="copy"></button><span class="lang">sql</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#F78C6C;">create</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">database</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">xue</span><span style="color:#A6ACCD;">;</span></span>
<span class="line"><span style="color:#F78C6C;">use</span><span style="color:#A6ACCD;"> xue;</span></span>
<span class="line"><span style="color:#F78C6C;">drop</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">table</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">if</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">exists</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">`</span><span style="color:#C3E88D;">tb_user</span><span style="color:#89DDFF;">`</span><span style="color:#A6ACCD;">;</span></span>
<span class="line"><span style="color:#F78C6C;">create</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">table</span><span style="color:#A6ACCD;"> `</span><span style="color:#82AAFF;">tb_user</span><span style="color:#A6ACCD;">`  (</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">`</span><span style="color:#C3E88D;">id</span><span style="color:#89DDFF;">`</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">bigint</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">20</span><span style="color:#A6ACCD;">) unsigned </span><span style="color:#F78C6C;">not null</span><span style="color:#A6ACCD;"> auto_increment comment </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">主键</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">`</span><span style="color:#C3E88D;">phone</span><span style="color:#89DDFF;">`</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">varchar</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">11</span><span style="color:#A6ACCD;">) </span><span style="color:#F78C6C;">not null</span><span style="color:#A6ACCD;"> comment </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">手机号码</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">`</span><span style="color:#C3E88D;">password</span><span style="color:#89DDFF;">`</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">varchar</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">128</span><span style="color:#A6ACCD;">) </span><span style="color:#F78C6C;">null</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">default</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&#39;&#39;</span><span style="color:#A6ACCD;"> comment </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">密码，加密存储</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">`</span><span style="color:#C3E88D;">nick_name</span><span style="color:#89DDFF;">`</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">varchar</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">32</span><span style="color:#A6ACCD;">) </span><span style="color:#F78C6C;">null</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">default</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&#39;&#39;</span><span style="color:#A6ACCD;"> comment </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">昵称，默认是用户id</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">`</span><span style="color:#C3E88D;">icon</span><span style="color:#89DDFF;">`</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">varchar</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">255</span><span style="color:#A6ACCD;">) </span><span style="color:#F78C6C;">null</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">default</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&#39;&#39;</span><span style="color:#A6ACCD;"> comment </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">人物头像</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">`</span><span style="color:#C3E88D;">create_time</span><span style="color:#89DDFF;">`</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">timestamp</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">not null</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">default</span><span style="color:#A6ACCD;"> current_timestamp comment </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">创建时间</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">`</span><span style="color:#C3E88D;">update_time</span><span style="color:#89DDFF;">`</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">timestamp</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">not null</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">default</span><span style="color:#A6ACCD;"> current_timestamp </span><span style="color:#F78C6C;">on</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">update</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#A6ACCD;">    current_timestamp comment </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">更新时间</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#C792EA;">primary key</span><span style="color:#A6ACCD;"> (</span><span style="color:#89DDFF;">`</span><span style="color:#C3E88D;">id</span><span style="color:#89DDFF;">`</span><span style="color:#A6ACCD;">) </span><span style="color:#F78C6C;">using</span><span style="color:#A6ACCD;"> btree,</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F78C6C;">unique</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">index</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">`</span><span style="color:#C3E88D;">unique_key_phone</span><span style="color:#89DDFF;">`</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">`</span><span style="color:#C3E88D;">phone</span><span style="color:#89DDFF;">`</span><span style="color:#A6ACCD;">) </span><span style="color:#F78C6C;">using</span><span style="color:#A6ACCD;"> btree</span></span>
<span class="line"><span style="color:#A6ACCD;">) engine </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> innodb auto_increment </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1</span><span style="color:#A6ACCD;"> ;</span></span></code></pre></div><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2023.3.30/202305221421870.png" alt="image-20230522142141816" style="zoom:80%;"><div class="language-sql"><button title="Copy Code" class="copy"></button><span class="lang">sql</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#F78C6C;">insert into</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">`</span><span style="color:#C3E88D;">tb_user</span><span style="color:#89DDFF;">`</span><span style="color:#A6ACCD;">(id,phone,</span><span style="color:#F78C6C;">password</span><span style="color:#A6ACCD;">,nick_name,icon) </span><span style="color:#F78C6C;">values</span></span>
<span class="line"><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">1</span><span style="color:#A6ACCD;">, </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">13686869696</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;">, </span><span style="color:#89DDFF;">&#39;&#39;</span><span style="color:#A6ACCD;">, </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">小鱼同学</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;">, </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">/imgs/blogs/blog1.jpg</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;">),</span></span>
<span class="line"><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">2</span><span style="color:#A6ACCD;">, </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">13838411438</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;">, </span><span style="color:#89DDFF;">&#39;&#39;</span><span style="color:#A6ACCD;">, </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">可可今天不吃肉</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;">,</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">/imgs/icons/kkjtbcr.jpg</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;">),</span></span>
<span class="line"><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">4</span><span style="color:#A6ACCD;">, </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">13456789011</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;">, </span><span style="color:#89DDFF;">&#39;&#39;</span><span style="color:#A6ACCD;">, </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">人生大事</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;">, </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">/imgs/icons/kkjtbcr1.jpg</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;">),</span></span>
<span class="line"><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">5</span><span style="color:#A6ACCD;">, </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">13456789001</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;">, </span><span style="color:#89DDFF;">&#39;&#39;</span><span style="color:#A6ACCD;">, </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">毛遂自建</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;">, </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">/imgs/icons/kkjtbcr2.jpg</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;">);</span></span></code></pre></div><h3 id="坐标依赖" tabindex="-1">坐标依赖 <a class="header-anchor" href="#坐标依赖" aria-label="Permalink to &quot;坐标依赖&quot;">​</a></h3><div class="language-xml"><button title="Copy Code" class="copy"></button><span class="lang">xml</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">dependencies</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#676E95;font-style:italic;">&lt;!--spring-data-redis--&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">org.springframework.boot</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">spring-boot-starter-data-redis</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#676E95;font-style:italic;">&lt;!--commons-pool2连接池--&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">org.apache.commons</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">commons-pool2</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#676E95;font-style:italic;">&lt;!--spring-boot-starter-web--&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">org.springframework.boot</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">spring-boot-starter-web</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#676E95;font-style:italic;">&lt;!--mysql-connector-java--&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">mysql</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">mysql-connector-java</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">scope</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">runtime</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">scope</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#676E95;font-style:italic;">&lt;!--lombok--&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">org.projectlombok</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">lombok</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">optional</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">true</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">optional</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#676E95;font-style:italic;">&lt;!--spring-boot-starter-test--&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">org.springframework.boot</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">spring-boot-starter-test</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">scope</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">test</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">scope</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#676E95;font-style:italic;">&lt;!--mybatis-plus--&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">com.baomidou</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">mybatis-plus-boot-starter</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">version</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">3.4.3</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">version</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#676E95;font-style:italic;">&lt;!--hutool--&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">cn.hutool</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">hutool-all</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">version</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">5.7.17</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">version</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">dependencies</span><span style="color:#89DDFF;">&gt;</span></span></code></pre></div><h3 id="连接配置" tabindex="-1">连接配置 <a class="header-anchor" href="#连接配置" aria-label="Permalink to &quot;连接配置&quot;">​</a></h3><div class="language-yml"><button title="Copy Code" class="copy"></button><span class="lang">yml</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#F07178;">server</span><span style="color:#89DDFF;">:</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F07178;">port</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">8081</span></span>
<span class="line"><span style="color:#F07178;">spring</span><span style="color:#89DDFF;">:</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F07178;">application</span><span style="color:#89DDFF;">:</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#F07178;">name</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">hmdp</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F07178;">datasource</span><span style="color:#89DDFF;">:</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#F07178;">driver-class-name</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">com.mysql.cj.jdbc.Driver</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#F07178;">url</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">jdbc:mysql://127.0.0.1:3306/xue?useSSL=false&amp;serverTimezone=UTC</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#F07178;">username</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">root</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#F07178;">password</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">123456</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F07178;">redis</span><span style="color:#89DDFF;">:</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#F07178;">host</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">127.0.0.1</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#F07178;">port</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">6379</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;"># password: 123321</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#F07178;">lettuce</span><span style="color:#89DDFF;">:</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#F07178;">pool</span><span style="color:#89DDFF;">:</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#F07178;">max-active</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">10</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#F07178;">max-idle</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">10</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#F07178;">min-idle</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#F07178;">time-between-eviction-runs</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">10s</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F07178;">jackson</span><span style="color:#89DDFF;">:</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#F07178;">default-property-inclusion</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">non_null</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;"># JSON处理时忽略非空字段</span></span>
<span class="line"><span style="color:#F07178;">mybatis-plus</span><span style="color:#89DDFF;">:</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F07178;">type-aliases-package</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">com.hmdp.entity</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;"># 别名扫描包，在xml中写SQL有效</span></span>
<span class="line"><span style="color:#F07178;">logging</span><span style="color:#89DDFF;">:</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F07178;">level</span><span style="color:#89DDFF;">:</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#F07178;">com.hmdp</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">debug</span></span></code></pre></div><h3 id="统一返回结果" tabindex="-1">统一返回结果 <a class="header-anchor" href="#统一返回结果" aria-label="Permalink to &quot;统一返回结果&quot;">​</a></h3><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Data</span></span>
<span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">NoArgsConstructor</span></span>
<span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">AllArgsConstructor</span></span>
<span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">Result</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Boolean</span><span style="color:#A6ACCD;"> success</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> errorMsg</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Object</span><span style="color:#A6ACCD;"> data</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Long</span><span style="color:#A6ACCD;"> total</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Result</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">ok</span><span style="color:#89DDFF;">(){</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">Result</span><span style="color:#89DDFF;">(true,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">null,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">null,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">null);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Result</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">ok</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">Object</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">data</span><span style="color:#89DDFF;">){</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">Result</span><span style="color:#89DDFF;">(true,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">null,</span><span style="color:#A6ACCD;"> data</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">null);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Result</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">ok</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">List</span><span style="color:#89DDFF;">&lt;</span><span style="color:#C792EA;">?</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">data</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Long</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">total</span><span style="color:#89DDFF;">){</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">Result</span><span style="color:#89DDFF;">(true,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">null,</span><span style="color:#A6ACCD;"> data</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> total</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Result</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">fail</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">errorMsg</span><span style="color:#89DDFF;">){</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">Result</span><span style="color:#89DDFF;">(false,</span><span style="color:#A6ACCD;"> errorMsg</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">null,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">null);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><h3 id="正则工具类" tabindex="-1">正则工具类 <a class="header-anchor" href="#正则工具类" aria-label="Permalink to &quot;正则工具类&quot;">​</a></h3><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">abstract</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">RegexPatterns</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">    /**</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">     * 手机号正则</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">     */</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">final</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> PHONE_REGEX </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#A6ACCD;">                  </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">^1([38][0-9]|4[579]|5[0-3,5-9]|6[6]|7[0135678]|9[89])</span><span style="color:#A6ACCD;">\\</span><span style="color:#C3E88D;">d{8}$</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">    /**</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">     * 邮箱正则</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">     */</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">final</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> EMAIL_REGEX </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#A6ACCD;">                  </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(</span><span style="color:#A6ACCD;">\\</span><span style="color:#C3E88D;">.[a-zA-Z0-9_-]+)+$</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">    /**</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">     * 密码正则。4~32位的字母、数字、下划线</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">     */</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">final</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> PASSWORD_REGEX </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">^</span><span style="color:#A6ACCD;">\\</span><span style="color:#C3E88D;">w{4,32}$</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">    /**</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">     * 验证码正则, 6位数字或字母</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">     */</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">final</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> VERIFY_CODE_REGEX </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">^[a-zA-Z</span><span style="color:#A6ACCD;">\\</span><span style="color:#C3E88D;">d]{6}$</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">RegexUtils</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">    /**</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">     * 是否是无效手机格式</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">     * </span><span style="color:#F78C6C;font-style:italic;">@param</span><span style="color:#676E95;font-style:italic;"> </span><span style="color:#A6ACCD;font-style:italic;">phone</span><span style="color:#676E95;font-style:italic;"> 要校验的手机号</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">     * </span><span style="color:#F78C6C;font-style:italic;">@return</span><span style="color:#676E95;font-style:italic;"> true:符合，false：不符合</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">     */</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">boolean</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">isPhoneInvalid</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">phone</span><span style="color:#89DDFF;">){</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">mismatch</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">phone</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> RegexPatterns</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">PHONE_REGEX</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">    /**</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">     * 是否是无效邮箱格式</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">     * </span><span style="color:#F78C6C;font-style:italic;">@param</span><span style="color:#676E95;font-style:italic;"> </span><span style="color:#A6ACCD;font-style:italic;">email</span><span style="color:#676E95;font-style:italic;"> 要校验的邮箱</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">     * </span><span style="color:#F78C6C;font-style:italic;">@return</span><span style="color:#676E95;font-style:italic;"> true:符合，false：不符合</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">     */</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">boolean</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">isEmailInvalid</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">email</span><span style="color:#89DDFF;">){</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">mismatch</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">email</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> RegexPatterns</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">EMAIL_REGEX</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">    /**</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">     * 是否是无效验证码格式</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">     * </span><span style="color:#F78C6C;font-style:italic;">@param</span><span style="color:#676E95;font-style:italic;"> </span><span style="color:#A6ACCD;font-style:italic;">code</span><span style="color:#676E95;font-style:italic;"> 要校验的验证码</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">     * </span><span style="color:#F78C6C;font-style:italic;">@return</span><span style="color:#676E95;font-style:italic;"> true:符合，false：不符合</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">     */</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">boolean</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">isCodeInvalid</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">code</span><span style="color:#89DDFF;">){</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">mismatch</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">code</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> RegexPatterns</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">VERIFY_CODE_REGEX</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 校验是否不符合正则格式</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">boolean</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">mismatch</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">str</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">regex</span><span style="color:#89DDFF;">){</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">StrUtil</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">isBlank</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">str</span><span style="color:#89DDFF;">))</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">true;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">!</span><span style="color:#A6ACCD;">str</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">matches</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">regex</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><h3 id="user实体类和工具类" tabindex="-1">User实体类和工具类 <a class="header-anchor" href="#user实体类和工具类" aria-label="Permalink to &quot;User实体类和工具类&quot;">​</a></h3><p>登录完成返回实体类</p><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Data</span></span>
<span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">UserDTO</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Long</span><span style="color:#A6ACCD;"> id</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> nickName</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> icon</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Data</span></span>
<span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">EqualsAndHashCode</span><span style="color:#89DDFF;">(</span><span style="color:#FFCB6B;">callSuper</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">false)</span></span>
<span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Accessors</span><span style="color:#89DDFF;">(</span><span style="color:#FFCB6B;">chain</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">true)</span></span>
<span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">TableName</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">tb_user</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">User</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">implements</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">Serializable</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">final</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">long</span><span style="color:#A6ACCD;"> serialVersionUID </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1L</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//主键</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">TableId</span><span style="color:#89DDFF;">(</span><span style="color:#FFCB6B;">value</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">id</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">type</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> IdType</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">AUTO</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Long</span><span style="color:#A6ACCD;"> id</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//手机号码</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> phone</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//密码，加密存储</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> password</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//昵称，默认是随机字符</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> nickName</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//用户头像</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> icon</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//创建时间</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">LocalDateTime</span><span style="color:#A6ACCD;"> createTime</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//更新时间</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">LocalDateTime</span><span style="color:#A6ACCD;"> updateTime</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><p>登录实体类</p><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Data</span></span>
<span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">LoginFormDTO</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> phone</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> code</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> password</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><h3 id="controller" tabindex="-1">controller <a class="header-anchor" href="#controller" aria-label="Permalink to &quot;controller&quot;">​</a></h3><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Slf4j</span></span>
<span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">RestController</span></span>
<span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">RequestMapping</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/user</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">UserController</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Resource</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">IUserService</span><span style="color:#A6ACCD;"> userService</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Resource</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">IUserInfoService</span><span style="color:#A6ACCD;"> userInfoService</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 发送手机验证码</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">PostMapping</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">code</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Result</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">sendCode</span><span style="color:#89DDFF;">(@</span><span style="color:#C792EA;">RequestParam</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">phone</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">phone</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">HttpSession</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">session</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">// TODO 发送短信验证码并保存验证码</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> Result</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">fail</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">功能未完成</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 登录功能：loginForm 登录参数，包含手机号、验证码；或者手机号、密码</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">PostMapping</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/login</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Result</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">login</span><span style="color:#89DDFF;">(@</span><span style="color:#C792EA;">RequestBody</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">LoginFormDTO</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">loginForm</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">HttpSession</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">session</span><span style="color:#89DDFF;">){</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">// TODO 实现登录功能</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> Result</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">fail</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">功能未完成</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 登出功能</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">PostMapping</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/logout</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Result</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">logout</span><span style="color:#89DDFF;">(){</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">// TODO 实现登出功能</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> Result</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">fail</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">功能未完成</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">GetMapping</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/me</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Result</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">me</span><span style="color:#89DDFF;">(){</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">// TODO 获取当前登录的用户并返回</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> Result</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">fail</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">功能未完成</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">GetMapping</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/info/{id}</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Result</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">info</span><span style="color:#89DDFF;">(@</span><span style="color:#C792EA;">PathVariable</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">id</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Long</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">userId</span><span style="color:#89DDFF;">){</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">// 查询详情</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">UserInfo</span><span style="color:#A6ACCD;"> info </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> userInfoService</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getById</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">userId</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">info </span><span style="color:#89DDFF;">==</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">null)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">            </span><span style="color:#676E95;font-style:italic;">// 没有详情，应该是第一次查看详情</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> Result</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">ok</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">        info</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setCreateTime</span><span style="color:#89DDFF;">(null);</span></span>
<span class="line"><span style="color:#A6ACCD;">        info</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setUpdateTime</span><span style="color:#89DDFF;">(null);</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">// 返回</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> Result</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">ok</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">info</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><h2 id="session登录" tabindex="-1">Session登录 <a class="header-anchor" href="#session登录" aria-label="Permalink to &quot;Session登录&quot;">​</a></h2><h3 id="登录流程" tabindex="-1">登录流程 <a class="header-anchor" href="#登录流程" aria-label="Permalink to &quot;登录流程&quot;">​</a></h3><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img/image-20220314144723213.png" alt="image-20220314144723213" style="zoom:80%;"><h3 id="发送验证码" tabindex="-1">发送验证码 <a class="header-anchor" href="#发送验证码" aria-label="Permalink to &quot;发送验证码&quot;">​</a></h3><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2022.6.30/202207171026832.png" alt="image-20220717102638699" style="zoom:80%;"><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">PostMapping</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">code</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Result</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">sendCode</span><span style="color:#89DDFF;">(@</span><span style="color:#C792EA;">RequestParam</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">phone</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> phone</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#A6ACCD;">                       </span><span style="color:#C792EA;">HttpSession</span><span style="color:#A6ACCD;"> session</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// TODO 发送短信验证码并保存验证码</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> userService</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">sendCode</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">phone</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;">session</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">interface</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">IUserService</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">extends</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">IService</span><span style="color:#89DDFF;">&lt;</span><span style="color:#C792EA;">User</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">   </span><span style="color:#C792EA;">Result</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">sendCode</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">phone</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">HttpSession</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">session</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// UserServiceImpl</span></span>
<span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Override</span></span>
<span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Result</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">sendCode</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> phone</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">HttpSession</span><span style="color:#A6ACCD;"> session</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//1、校验手机号：正则&quot;^1([38][0-9]|4[579]|5[0-3,5-9]|6[6]|7[0135678]|9[89])\\d{8}$&quot;</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//   该正则是自己定义的工具类</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">RegexUtils</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">isPhoneInvalid</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">phone</span><span style="color:#89DDFF;">))</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">//2、如果不符合，返回错误信息</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> Result</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">fail</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">手机号格式错误</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//3、符合，生成验证码,RandomUtil是hutool工具包</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> code </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> RandomUtil</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">randomNumbers</span><span style="color:#89DDFF;">(</span><span style="color:#F78C6C;">6</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//4、保存验证码用session</span></span>
<span class="line"><span style="color:#A6ACCD;">    session</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setAttribute</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">code</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;">code</span><span style="color:#89DDFF;">);</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//5、发送验证码</span></span>
<span class="line"><span style="color:#A6ACCD;">    log</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">debug</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">发送验证码成功，验证码：{}</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;">code</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//返回ok，发送成功</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> Result</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">ok</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><blockquote><p>功能测试：<a href="http://127.0.0.1:8081/user/code" target="_blank" rel="noreferrer">http://127.0.0.1:8081/user/code</a></p></blockquote><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2023.3.30/202305221510334.png" alt="image-20230522151012267" style="zoom:80%;"><h3 id="登录功能实现" tabindex="-1">登录功能实现 <a class="header-anchor" href="#登录功能实现" aria-label="Permalink to &quot;登录功能实现&quot;">​</a></h3><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2022.6.30/202207171033024.png" alt="image-20220717103326930" style="zoom:67%;"><h4 id="entity" tabindex="-1">entity <a class="header-anchor" href="#entity" aria-label="Permalink to &quot;entity&quot;">​</a></h4><blockquote><p>LoginFormDTO：登录的表单信息</p></blockquote><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Data</span></span>
<span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">LoginFormDTO</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> phone</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> code</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> password</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><blockquote><p>UserDTO：返回的数据信息，不能带密码</p></blockquote><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Data</span></span>
<span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">UserDTO</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Long</span><span style="color:#A6ACCD;"> id</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> nickName</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> icon</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><h4 id="usercontroller" tabindex="-1">UserController <a class="header-anchor" href="#usercontroller" aria-label="Permalink to &quot;UserController&quot;">​</a></h4><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">PostMapping</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">login</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Result</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">login</span><span style="color:#89DDFF;">(@</span><span style="color:#C792EA;">RequestBody</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">LoginFormDTO</span><span style="color:#A6ACCD;"> loginForm</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">                    </span><span style="color:#C792EA;">HttpSession</span><span style="color:#A6ACCD;"> session</span><span style="color:#89DDFF;">){</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// TODO 实现登录功能</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> userService</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">login</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">loginForm</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;">session</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><h4 id="iuserservice" tabindex="-1">IUserService <a class="header-anchor" href="#iuserservice" aria-label="Permalink to &quot;IUserService&quot;">​</a></h4><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">interface</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">IUserService</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">extends</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">IService</span><span style="color:#89DDFF;">&lt;</span><span style="color:#C792EA;">User</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">	</span><span style="color:#676E95;font-style:italic;">// 发送验证码</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">Result</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">sendCode</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">phone</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">HttpSession</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">session</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#89DDFF;">  	</span><span style="color:#676E95;font-style:italic;">// 登录功能</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">Result</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">login</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">LoginFormDTO</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">loginForm</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">HttpSession</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">session</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><h4 id="userserviceimpl" tabindex="-1">UserServiceImpl <a class="header-anchor" href="#userserviceimpl" aria-label="Permalink to &quot;UserServiceImpl&quot;">​</a></h4><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Override</span></span>
<span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Result</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">login</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">LoginFormDTO</span><span style="color:#A6ACCD;"> loginForm</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">HttpSession</span><span style="color:#A6ACCD;"> session</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//1、先校验手机号</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> phone </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> loginForm</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getPhone</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">RegexUtils</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">isPhoneInvalid</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">phone</span><span style="color:#89DDFF;">))</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">//2、如果不符合，返回错误信息</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> Result</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">fail</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">手机号格式错误</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//2、再校验验证码，从session取出验证码，再和输入的验证码进行比较</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">Object</span><span style="color:#A6ACCD;"> cacheCode </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> session</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getAttribute</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">code</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">);</span><span style="color:#A6ACCD;">   </span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> code </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> loginForm</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getCode</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">cacheCode </span><span style="color:#89DDFF;">==</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">null</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">||</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">!</span><span style="color:#A6ACCD;">cacheCode</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">equals</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">code</span><span style="color:#89DDFF;">))</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">//3、不一致，报错</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> Result</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">fail</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">验证码错误</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//4、一致，根据手机号查询用户select * from tb_user where phone = ?</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">User</span><span style="color:#A6ACCD;"> user </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">query</span><span style="color:#89DDFF;">().</span><span style="color:#82AAFF;">eq</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">phone</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> phone</span><span style="color:#89DDFF;">).</span><span style="color:#82AAFF;">one</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//5、判断用户是否存在</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">user </span><span style="color:#89DDFF;">==</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">null)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">//6、不存在，创建新用户保存</span></span>
<span class="line"><span style="color:#A6ACCD;">        user </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">createUserWithPhone</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">phone</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//7、保存用户信息到session中，</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//注意：这边要隐藏用户敏感信息,将user当中的属性拷贝到UserDTO(user的部分属性)中</span></span>
<span class="line"><span style="color:#A6ACCD;">    session</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setAttribute</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">user</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#A6ACCD;">                         BeanUtil</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">copyProperties</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">user</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> UserDTO</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">class</span><span style="color:#89DDFF;">));</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//session保存不需要返回保存内容</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> Result</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">ok</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><blockquote><p>UserServiceImpl：注册目前无需写接口，登陆时用户不存在直接创建，因此只写实现即可</p></blockquote><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">User</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">createUserWithPhone</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> phone</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//1、创建用户</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">User</span><span style="color:#A6ACCD;"> user </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">User</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">    user</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setPhone</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">phone</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 随机生成昵称</span></span>
<span class="line"><span style="color:#A6ACCD;">    user</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setNickName</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">user_</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">+</span><span style="color:#A6ACCD;">RandomUtil</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">randomString</span><span style="color:#89DDFF;">(</span><span style="color:#F78C6C;">10</span><span style="color:#89DDFF;">));</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//2、保存用户，save是MybatisPlus的方法</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#82AAFF;">save</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">user</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> user</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><h4 id="功能测试" tabindex="-1">功能测试 <a class="header-anchor" href="#功能测试" aria-label="Permalink to &quot;功能测试&quot;">​</a></h4><blockquote><p>发送验证码</p></blockquote><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2023.3.30/202305221532478.png" alt="image-20230522153231424" style="zoom:80%;"><blockquote><p>进行登录</p></blockquote><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2023.3.30/202305221532171.png" alt="image-20230522153259119" style="zoom:80%;"><h3 id="登录校验拦截器" tabindex="-1">登录校验拦截器 <a class="header-anchor" href="#登录校验拦截器" aria-label="Permalink to &quot;登录校验拦截器&quot;">​</a></h3><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2022.6.30/202207171034824.png" alt="image-20220717103431751" style="zoom:67%;"><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img/image-20220314154403399.png" alt="image-20220314154403399" style="zoom:67%;"><h4 id="threadlocal" tabindex="-1">ThreadLocal <a class="header-anchor" href="#threadlocal" aria-label="Permalink to &quot;ThreadLocal&quot;">​</a></h4><p>用来保存用户信息</p><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">UserHolder</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 创建ThreadLocal对象</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">final</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">ThreadLocal</span><span style="color:#89DDFF;">&lt;</span><span style="color:#C792EA;">UserDTO</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> tl </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">ThreadLocal</span><span style="color:#89DDFF;">&lt;&gt;();</span></span>
<span class="line"><span style="color:#89DDFF;">	</span><span style="color:#676E95;font-style:italic;">// 创建存、取、删、静态方法</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">void</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">saveUser</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">UserDTO</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">userId</span><span style="color:#89DDFF;">){</span></span>
<span class="line"><span style="color:#A6ACCD;">        tl</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">set</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">userId</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">UserDTO</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">getUser</span><span style="color:#89DDFF;">(){</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> tl</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">get</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">void</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">removeUser</span><span style="color:#89DDFF;">(){</span></span>
<span class="line"><span style="color:#A6ACCD;">        tl</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">remove</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><h4 id="logininterceptor" tabindex="-1">LoginInterceptor <a class="header-anchor" href="#logininterceptor" aria-label="Permalink to &quot;LoginInterceptor&quot;">​</a></h4><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">LoginInterceptor</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">implements</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">HandlerInterceptor</span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">boolean</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">preHandle</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">HttpServletRequest</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">request</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#A6ACCD;">                             </span><span style="color:#C792EA;">HttpServletResponse</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">response</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#A6ACCD;">                             </span><span style="color:#C792EA;">Object</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">handler</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">throws</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Exception</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">//1、获取session</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">HttpSession</span><span style="color:#A6ACCD;"> session </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> request</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getSession</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">//2、获取session中的用户</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">Object</span><span style="color:#A6ACCD;"> user </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> session</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getAttribute</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">user</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">//3、判断用户是否存在</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">user </span><span style="color:#89DDFF;">==</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">null)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">            </span><span style="color:#676E95;font-style:italic;">//不存在，拦截，返回401状态码</span></span>
<span class="line"><span style="color:#A6ACCD;">            response</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setStatus</span><span style="color:#89DDFF;">(</span><span style="color:#F78C6C;">401</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">false;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">  </span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">//5、存在，保存信息到ThreadLocal</span></span>
<span class="line"><span style="color:#A6ACCD;">        UserHolder</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">saveUser</span><span style="color:#89DDFF;">((</span><span style="color:#A6ACCD;">UserDTO</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;">user</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">//6、放行</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">true;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">void</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">afterCompletion</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">HttpServletRequest</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">request</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">                                </span><span style="color:#C792EA;">HttpServletResponse</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">response</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#A6ACCD;">                                </span><span style="color:#C792EA;">Object</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">handler</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Nullable</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Exception</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">ex</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">throws</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Exception</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">//移除用户，避免内存泄露</span></span>
<span class="line"><span style="color:#A6ACCD;">        UserHolder</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">removeUser</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><h4 id="mvcconfig" tabindex="-1">MvcConfig <a class="header-anchor" href="#mvcconfig" aria-label="Permalink to &quot;MvcConfig&quot;">​</a></h4><blockquote><p>拦截器写好后还需要配置，不然不会生效</p></blockquote><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Configuration</span></span>
<span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">MvcConfig</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">implements</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">WebMvcConfigurer</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Override</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">void</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">addInterceptors</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">InterceptorRegistry</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">registry</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">// 拦截器注册，添加排除不需要拦截的路径</span></span>
<span class="line"><span style="color:#A6ACCD;">        registry</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">addInterceptor</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;font-style:italic;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">LoginInterceptor</span><span style="color:#89DDFF;">())</span></span>
<span class="line"><span style="color:#A6ACCD;">                </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">excludePathPatterns</span><span style="color:#89DDFF;">(</span></span>
<span class="line"><span style="color:#A6ACCD;">                        </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/shop/**</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">                        </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/voucher/**</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">                        </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/shop-type/**</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">                        </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/upload/**</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">                        </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/blog/hot</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">                        </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/user/code</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">                        </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/user/login</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">                        </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/swagger-resources/**</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">                        </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/webjars/**</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/v2/**</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">                        </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/swagger-ui.html/**</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">                </span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><h4 id="usercontroller-1" tabindex="-1">UserController <a class="header-anchor" href="#usercontroller-1" aria-label="Permalink to &quot;UserController&quot;">​</a></h4><blockquote><p>登录成功获取用户</p></blockquote><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">GetMapping</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">me</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Result</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">me</span><span style="color:#89DDFF;">(){</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// TODO 获取当前登录的用户并返回，在拦截器中已经把用户信息放到UserHolder里面了</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">UserDTO</span><span style="color:#A6ACCD;"> user </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> UserHolder</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getUser</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> Result</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">ok</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">user</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><h4 id="访问测试" tabindex="-1">访问测试 <a class="header-anchor" href="#访问测试" aria-label="Permalink to &quot;访问测试&quot;">​</a></h4><blockquote><p>前面获取验证码和登录流程和上面一样，接下来只需要调用me方法获取信息即可</p></blockquote><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2023.3.30/202305221551375.png" alt="image-20230522155113319" style="zoom:80%;"><h3 id="集群共享问题" tabindex="-1">集群共享问题 <a class="header-anchor" href="#集群共享问题" aria-label="Permalink to &quot;集群共享问题&quot;">​</a></h3><blockquote><p><strong>Session共享问题</strong>：<strong>多台Tomcat并不共享session存储空间，当请求切换到不同tomcat服务时导致数据丢失的问题</strong>。session的替代方案应该满足：</p></blockquote><blockquote><ul><li><p>数据共享</p></li><li><p>内存存储</p></li><li><p>key、value结构</p></li></ul></blockquote><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img/image-20220314154521491.png" alt="image-20220314154521491" style="zoom:67%;"><h2 id="redis登录" tabindex="-1">Redis登录 <a class="header-anchor" href="#redis登录" aria-label="Permalink to &quot;Redis登录&quot;">​</a></h2><h3 id="流程图解" tabindex="-1">流程图解 <a class="header-anchor" href="#流程图解" aria-label="Permalink to &quot;流程图解&quot;">​</a></h3><h4 id="登录注册" tabindex="-1">登录注册 <a class="header-anchor" href="#登录注册" aria-label="Permalink to &quot;登录注册&quot;">​</a></h4><blockquote><p>每一个用户都是唯一的，因此redis的key是唯一的</p></blockquote><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img/image-20220314160722513.png" alt="image-20220314160722513" style="zoom:67%;"><h4 id="校验状态" tabindex="-1">校验状态 <a class="header-anchor" href="#校验状态" aria-label="Permalink to &quot;校验状态&quot;">​</a></h4><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img/image-20220314160757368.png" alt="image-20220314160757368" style="zoom:67%;"><h3 id="信息保存格式" tabindex="-1">信息保存格式 <a class="header-anchor" href="#信息保存格式" aria-label="Permalink to &quot;信息保存格式&quot;">​</a></h3><blockquote><p>保存登录的用户信息，可以使用String结构，以JSON字符串来保存，比较直观</p></blockquote><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img/image-20220314160840149.png" alt="image-20220314160840149" style="zoom:67%;"><blockquote><p>Hash结构可以将对象中的每个字段独立存储，可以针对单个字段做CRUD，并且内存占用更少</p></blockquote><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img/image-20220314160905860.png" alt="image-20220314160905860" style="zoom:67%;"><p>Redis代替session需要考虑的问题：</p><ul><li>选择合适的数据结构</li><li>选择合适的key</li><li>选择合适的存储粒度</li></ul><h3 id="前端逻辑⭐" tabindex="-1">前端逻辑⭐ <a class="header-anchor" href="#前端逻辑⭐" aria-label="Permalink to &quot;前端逻辑⭐&quot;">​</a></h3><blockquote><p>就是请求头添加一个authorization，把token保存在里面</p></blockquote><blockquote><p>login.vue</p></blockquote><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#82AAFF;">login</span><span style="color:#A6ACCD;">() </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">!this.</span><span style="color:#A6ACCD;">radio</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#89DDFF;">this.</span><span style="color:#A6ACCD;">$message</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">error</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">请先确认阅读用户协议</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#89DDFF;font-style:italic;">return</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">!this.</span><span style="color:#A6ACCD;">form</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">phone</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">||</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">!this.</span><span style="color:#A6ACCD;">form</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">code</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#89DDFF;">this.</span><span style="color:#A6ACCD;">$message</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">error</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">手机号和验证码不能为空</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#89DDFF;font-style:italic;">return</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">axios</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">post</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/user/login</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,this.</span><span style="color:#A6ACCD;">form</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">then</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">({</span><span style="color:#A6ACCD;font-style:italic;">data</span><span style="color:#89DDFF;">})</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">// 保存用户信息到session</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#A6ACCD;">sessionStorage</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setItem</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">token</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;">data</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 跳转到首页</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">location</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">href</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/info.html</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><blockquote><p>axios请求工具类</p></blockquote><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// request拦截器，将用户token放入头中</span></span>
<span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> token </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> sessionStorage</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getItem</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">token</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">axios</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">interceptors</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">request</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">use</span><span style="color:#A6ACCD;">(</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#A6ACCD;font-style:italic;">config</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">token</span><span style="color:#F07178;">) </span><span style="color:#A6ACCD;">config</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">headers</span><span style="color:#F07178;">[</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">authorization</span><span style="color:#89DDFF;">&#39;</span><span style="color:#F07178;">] </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">token</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">config</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">},</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#A6ACCD;font-style:italic;">error</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">error</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#FFCB6B;">Promise</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">reject</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">error</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">)</span></span></code></pre></div><h3 id="redis常量类" tabindex="-1">Redis常量类 <a class="header-anchor" href="#redis常量类" aria-label="Permalink to &quot;Redis常量类&quot;">​</a></h3><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">RedisConstants</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 验证码，时间</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">final</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> LOGIN_CODE_KEY </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">login:code:</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">final</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Long</span><span style="color:#A6ACCD;"> LOGIN_CODE_TTL </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">200L</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">final</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">TimeUnit</span><span style="color:#A6ACCD;"> LOGIN_CODE_TIME </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> TimeUnit</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">SECONDS</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 登录用户信息</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">final</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> LOGIN_USER_KEY </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">login:token:</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">final</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Long</span><span style="color:#A6ACCD;"> LOGIN_USER_TTL </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">250L</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">final</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">TimeUnit</span><span style="color:#A6ACCD;"> LOGIN_USER_TIME </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> TimeUnit</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">SECONDS</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><h3 id="发送验证码-1" tabindex="-1">发送验证码 <a class="header-anchor" href="#发送验证码-1" aria-label="Permalink to &quot;发送验证码&quot;">​</a></h3><blockquote><p>修改上面的session登录即可</p></blockquote><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">PostMapping</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">code</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Result</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">sendCode</span><span style="color:#89DDFF;">(@</span><span style="color:#C792EA;">RequestParam</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">phone</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> phone</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// TODO 发送短信验证码并保存验证码</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> userService</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">sendCode</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">phone</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#C792EA;">Result</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">sendCode</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> phone</span><span style="color:#89DDFF;">);</span></span></code></pre></div><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Resource</span></span>
<span class="line"><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">StringRedisTemplate</span><span style="color:#A6ACCD;"> stringRedisTemplate</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Override</span></span>
<span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Result</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">sendCode</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> phone</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//1、校验手机号</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">RegexUtils</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">isPhoneInvalid</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">phone</span><span style="color:#89DDFF;">))</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">//2、如果不符合，返回错误信息</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> Result</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">fail</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">手机号格式错误</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//3、符合，生成验证码</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> code </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> RandomUtil</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">randomNumbers</span><span style="color:#89DDFF;">(</span><span style="color:#F78C6C;">6</span><span style="color:#89DDFF;">);</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//改用redis,设置有效期,设置常量</span></span>
<span class="line"><span style="color:#A6ACCD;">    stringRedisTemplate</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">opsForValue</span><span style="color:#89DDFF;">()</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">set</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">RedisConstants</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">LOGIN_CODE_KEY </span><span style="color:#89DDFF;">+</span><span style="color:#A6ACCD;">phone</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;">code</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">                 RedisConstants</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">LOGIN_CODE_TTL</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> RedisConstants</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">LOGIN_CODE_TIME</span><span style="color:#89DDFF;">);</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//5、发送验证码</span></span>
<span class="line"><span style="color:#A6ACCD;">    log</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">debug</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">发送验证码成功，验证码：{}</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;">code</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//返回ok</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> Result</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">ok</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><h3 id="登录功能实现-1" tabindex="-1">登录功能实现 <a class="header-anchor" href="#登录功能实现-1" aria-label="Permalink to &quot;登录功能实现&quot;">​</a></h3><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">//登录参数，包含手机号、验证码；或者手机号、密码</span></span>
<span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">PostMapping</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">login</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Result</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">login</span><span style="color:#89DDFF;">(@</span><span style="color:#C792EA;">RequestBody</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">LoginFormDTO</span><span style="color:#A6ACCD;"> loginForm</span><span style="color:#89DDFF;">){</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// TODO 实现登录功能</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> userService</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">login</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">loginForm</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#C792EA;">Result</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">login</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">LoginFormDTO</span><span style="color:#A6ACCD;"> loginForm</span><span style="color:#89DDFF;">);</span></span></code></pre></div><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Override</span></span>
<span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Result</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">login</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">LoginFormDTO</span><span style="color:#A6ACCD;"> loginForm</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//1、校验手机号</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> phone </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> loginForm</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getPhone</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">RegexUtils</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">isPhoneInvalid</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">phone</span><span style="color:#89DDFF;">))</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">//2、如果不符合，返回错误信息</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> Result</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">fail</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">手机号格式错误</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//2、校验验证码，从redis获取验证码并校验</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> cacheCode </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> stringRedisTemplate</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">opsForValue</span><span style="color:#89DDFF;">()</span></span>
<span class="line"><span style="color:#A6ACCD;">                       </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">get</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">RedisConstants</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">LOGIN_CODE_KEY </span><span style="color:#89DDFF;">+</span><span style="color:#A6ACCD;"> phone</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> code </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> loginForm</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getCode</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//打印一下，看看两个是否相同</span></span>
<span class="line"><span style="color:#A6ACCD;">    log</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">info</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">code:{},cacheCode:{}</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;">code</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;">cacheCode</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//3、验证码不一致或不存在，报错</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">cacheCode </span><span style="color:#89DDFF;">==</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">null</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">||</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">!</span><span style="color:#A6ACCD;">cacheCode</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">equals</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">code</span><span style="color:#89DDFF;">))</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> Result</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">fail</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">验证码错误</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//4、一致，根据手机号查询用户select * from tb_user where phone = ?</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">User</span><span style="color:#A6ACCD;"> user </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">query</span><span style="color:#89DDFF;">().</span><span style="color:#82AAFF;">eq</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">phone</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> phone</span><span style="color:#89DDFF;">).</span><span style="color:#82AAFF;">one</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//5、判断用户是否存在</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">user </span><span style="color:#89DDFF;">==</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">null)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">//6、不存在，创建新用户保存(下面的方法)</span></span>
<span class="line"><span style="color:#A6ACCD;">        user </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">createUserWithPhone</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">phone</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//7、将信息保存到redis中，随机生成token，作为登录令牌，这不是标准的token，只是UUID</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> token </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> UUID</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">randomUUID</span><span style="color:#89DDFF;">().</span><span style="color:#82AAFF;">toString</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//8、将user对象里的部分信息复制到userDTO中(保护隐私)</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">UserDTO</span><span style="color:#A6ACCD;"> userDTO </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> BeanUtil</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">copyProperties</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">user</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> UserDTO</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">class</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//9、将UserDTO对象转为HashMap存储，下面这种情况是普通用法</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//Map&lt;String, Object&gt; userMap = BeanUtil.beanToMap(userDTO);</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//因为stringRedisTemplate要求对象内部全是string才行，因此里面用到string转换</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">Map</span><span style="color:#89DDFF;">&lt;</span><span style="color:#C792EA;">String</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Object</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> userMap </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> BeanUtil</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">beanToMap</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">userDTO</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;font-style:italic;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">HashMap</span><span style="color:#89DDFF;">&lt;&gt;(),</span></span>
<span class="line"><span style="color:#A6ACCD;">            CopyOptions</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">create</span><span style="color:#89DDFF;">()</span></span>
<span class="line"><span style="color:#A6ACCD;">                    </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setIgnoreNullValue</span><span style="color:#89DDFF;">(true)</span></span>
<span class="line"><span style="color:#89DDFF;">                     </span><span style="color:#676E95;font-style:italic;">// 将字段值全部转换成String类型                                </span></span>
<span class="line"><span style="color:#A6ACCD;">                    </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setFieldValueEditor</span><span style="color:#89DDFF;">((</span><span style="color:#A6ACCD;">fieldName</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;">fieldValue</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">-&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">                            fieldValue</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">toString</span><span style="color:#89DDFF;">()));</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//存储,这个是为了存储在redis中，返回给前端的只需要token</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> tokenKey </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> RedisConstants</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">LOGIN_USER_KEY</span><span style="color:#89DDFF;">+</span><span style="color:#A6ACCD;">token</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">    log</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">info</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">tokenKey:</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">+</span><span style="color:#A6ACCD;">tokenKey</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//将信息保存到hash</span></span>
<span class="line"><span style="color:#A6ACCD;">    stringRedisTemplate</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">opsForHash</span><span style="color:#89DDFF;">().</span><span style="color:#82AAFF;">putAll</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">tokenKey</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;">userMap</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//获取存储的hash信息</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">Map</span><span style="color:#89DDFF;">&lt;</span><span style="color:#C792EA;">Object</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Object</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> userMap1 </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> stringRedisTemplate</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">opsForHash</span><span style="color:#89DDFF;">().</span><span style="color:#82AAFF;">entries</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">tokenKey</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//设置token有效期</span></span>
<span class="line"><span style="color:#A6ACCD;">    stringRedisTemplate</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">expire</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">tokenKey</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;">RedisConstants</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">LOGIN_USER_TTL</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">                               RedisConstants</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">LOGIN_USER_TIME</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//注意把token返回</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> Result</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">ok</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">token</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><blockquote><p>用户不存在创建用户(和session中一样)</p></blockquote><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">User</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">createUserWithPhone</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> phone</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//1、创建用户</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">User</span><span style="color:#A6ACCD;"> user </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">User</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">    user</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setPhone</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">phone</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">    user</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setNickName</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">user_</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">+</span><span style="color:#A6ACCD;">RandomUtil</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">randomString</span><span style="color:#89DDFF;">(</span><span style="color:#F78C6C;">10</span><span style="color:#89DDFF;">));</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//2、保存用户</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#82AAFF;">save</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">user</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> user</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2022.5/202205052107563.png" alt="image-20220505210738458" style="zoom:80%;"><h3 id="拦截器⭐" tabindex="-1">拦截器⭐ <a class="header-anchor" href="#拦截器⭐" aria-label="Permalink to &quot;拦截器⭐&quot;">​</a></h3><blockquote><p><strong>因为目前拦截器只拦截需要登录校验的路径，而一些如首页等路径是不会去拦截的，如果用户不去访问这些路径，拦截器的token有效期就不会刷新，这样token有效期到了登录就会失效</strong>。我们想让拦截器只要用户访问任何路径都会触发，这样就能一直刷新token有效期了。<strong>即token必须是自动续期的</strong></p></blockquote><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2022.6.30/202207171132072.png" alt="image-20220717113218979" style="zoom:67%;"><p>拦截器优化</p><blockquote><p>第一个拦截器拦截所有路径，这样能一直刷新登录有效期，第二个拦截器拦截登录请求</p></blockquote><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2022.5/202205052118051.png" alt="image-20220505211817932" style="zoom:80%;"><h4 id="userholder" tabindex="-1">UserHolder <a class="header-anchor" href="#userholder" aria-label="Permalink to &quot;UserHolder&quot;">​</a></h4><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">UserHolder</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">final</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">ThreadLocal</span><span style="color:#89DDFF;">&lt;</span><span style="color:#C792EA;">UserDTO</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> tl </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">ThreadLocal</span><span style="color:#89DDFF;">&lt;&gt;();</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">void</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">saveUser</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">UserDTO</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">user</span><span style="color:#89DDFF;">){</span></span>
<span class="line"><span style="color:#A6ACCD;">        tl</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">set</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">user</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">UserDTO</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">getUser</span><span style="color:#89DDFF;">(){</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> tl</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">get</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">void</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">removeUser</span><span style="color:#89DDFF;">(){</span></span>
<span class="line"><span style="color:#A6ACCD;">        tl</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">remove</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><h4 id="refreshtokeninterceptor" tabindex="-1">RefreshTokenInterceptor <a class="header-anchor" href="#refreshtokeninterceptor" aria-label="Permalink to &quot;RefreshTokenInterceptor&quot;">​</a></h4><blockquote><p>第一个拦截器，拦截所有请求，但目标只是为了刷新token，无论token是否存在，路径都能访问通过</p><p>注意：拦截所有请求是在配置类中设置</p></blockquote><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">RefreshTokenInterceptor</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">implements</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">HandlerInterceptor</span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">	</span><span style="color:#676E95;font-style:italic;">// 注入stringRedisTemplate</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;">  </span><span style="color:#C792EA;">StringRedisTemplate</span><span style="color:#A6ACCD;"> stringRedisTemplate</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//因为不是Spring的类，不能@Resource注入，所以要使用构造函数来注入</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">RefreshTokenInterceptor</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">StringRedisTemplate</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">stringRedisTemplate</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">this.</span><span style="color:#A6ACCD;">stringRedisTemplate </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> stringRedisTemplate</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">	</span><span style="color:#676E95;font-style:italic;">// 前置拦截器</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">boolean</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">preHandle</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">HttpServletRequest</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">request</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#A6ACCD;">                             </span><span style="color:#C792EA;">HttpServletResponse</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">response</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#A6ACCD;">                             </span><span style="color:#C792EA;">Object</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">handler</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">throws</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Exception</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">//获取请求头的token，前端传过来的</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> token </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> request</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getHeader</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">authorization</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">//判断token是否为空，为空也放行，感觉没必要判断，StrUtil是hutool工具包</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">StrUtil</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">isBlank</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">token</span><span style="color:#89DDFF;">))</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">true;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">//2、获取Redis中的用户，从Hash类型中取到</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> key </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> RedisConstants</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">LOGIN_USER_KEY </span><span style="color:#89DDFF;">+</span><span style="color:#A6ACCD;"> token</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">Map</span><span style="color:#89DDFF;">&lt;</span><span style="color:#C792EA;">Object</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Object</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> userMap </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> stringRedisTemplate</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">opsForHash</span><span style="color:#89DDFF;">().</span><span style="color:#82AAFF;">entries</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">key</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">//判断用户是否存在，这里同样不要拦截，直接放行，感觉没必要判断</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">userMap</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">isEmpty</span><span style="color:#89DDFF;">())</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">true;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">//5、将查询到的Hash数据转换为userDTO对象，第三个参数表示是否忽略错误，false不忽略</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">UserDTO</span><span style="color:#A6ACCD;"> userDTO </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> BeanUtil</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">fillBeanWithMap</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">userMap</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#A6ACCD;">                                                   </span><span style="color:#89DDFF;font-style:italic;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">UserDTO</span><span style="color:#89DDFF;">(),</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">false);</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">//6、存在，保存用户信息到ThreadLocal</span></span>
<span class="line"><span style="color:#A6ACCD;">        UserHolder</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">saveUser</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">userDTO</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">//6、放行</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">//7、刷新token有效期</span></span>
<span class="line"><span style="color:#A6ACCD;">        stringRedisTemplate</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">expire</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">key</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;">RedisConstants</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">LOGIN_USER_TTL</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">                                       RedisConstants</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">LOGIN_USER_TIME</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">true;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">void</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">afterCompletion</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">HttpServletRequest</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">request</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#A6ACCD;">                                </span><span style="color:#C792EA;">HttpServletResponse</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">response</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#A6ACCD;">                                </span><span style="color:#C792EA;">Object</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">handler</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Nullable</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Exception</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">ex</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">throws</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Exception</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">//移除用户</span></span>
<span class="line"><span style="color:#A6ACCD;">        UserHolder</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">removeUser</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><h4 id="logininterceptor-1" tabindex="-1">LoginInterceptor <a class="header-anchor" href="#logininterceptor-1" aria-label="Permalink to &quot;LoginInterceptor&quot;">​</a></h4><blockquote><p>第二个拦截器，负责真正的拦截动作</p></blockquote><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">LoginInterceptor</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">implements</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">HandlerInterceptor</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">boolean</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">preHandle</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">HttpServletRequest</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">request</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#A6ACCD;">                             </span><span style="color:#C792EA;">HttpServletResponse</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">response</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#A6ACCD;">                             </span><span style="color:#C792EA;">Object</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">handler</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">throws</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Exception</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">//判读是否需要拦截(ThreadLocal中是否有用户)</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">UserHolder</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getUser</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">==</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">null)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">            </span><span style="color:#676E95;font-style:italic;">//没有用户，需要拦截，并设置状态码</span></span>
<span class="line"><span style="color:#A6ACCD;">            response</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setStatus</span><span style="color:#89DDFF;">(</span><span style="color:#F78C6C;">401</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">false;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">//有用户，放行</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">true;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><h4 id="mvcconfig-1" tabindex="-1">MvcConfig <a class="header-anchor" href="#mvcconfig-1" aria-label="Permalink to &quot;MvcConfig&quot;">​</a></h4><blockquote><p>注册拦截器</p></blockquote><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Configuration</span></span>
<span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">MvcConfig</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">implements</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">WebMvcConfigurer</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Resource</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">StringRedisTemplate</span><span style="color:#A6ACCD;"> stringRedisTemplate</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Override</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">void</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">addInterceptors</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">InterceptorRegistry</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">registry</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">//order表示执行先后顺序，order越大越晚执行，确保第一个拦截器一定在第二个前面执行</span></span>
<span class="line"><span style="color:#A6ACCD;">        registry</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">addInterceptor</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;font-style:italic;">new</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#A6ACCD;">                                </span><span style="color:#82AAFF;">RefreshTokenInterceptor</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">stringRedisTemplate</span><span style="color:#89DDFF;">))</span></span>
<span class="line"><span style="color:#89DDFF;">                </span><span style="color:#676E95;font-style:italic;">// 拦截一切路径</span></span>
<span class="line"><span style="color:#A6ACCD;">                </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">addPathPatterns</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/**</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">).</span><span style="color:#82AAFF;">order</span><span style="color:#89DDFF;">(</span><span style="color:#F78C6C;">0</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">        registry</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">addInterceptor</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;font-style:italic;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">LoginInterceptor</span><span style="color:#89DDFF;">())</span></span>
<span class="line"><span style="color:#89DDFF;">                </span><span style="color:#676E95;font-style:italic;">// 只拦截需要登录的路径，即放行不需要登录的路径</span></span>
<span class="line"><span style="color:#A6ACCD;">                </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">excludePathPatterns</span><span style="color:#89DDFF;">(</span></span>
<span class="line"><span style="color:#A6ACCD;">                        </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/shop/**</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">                        </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/voucher/**</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">                        </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/shop-type/**</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">                        </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/upload/**</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">                        </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/blog/hot</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">                        </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/user/code</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">                        </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/user/login</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">                        </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/swagger-resources/**</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">                        </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/webjars/**</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/v2/**</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">                        </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/swagger-ui.html/**</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">                </span><span style="color:#89DDFF;">).</span><span style="color:#82AAFF;">order</span><span style="color:#89DDFF;">(</span><span style="color:#F78C6C;">1</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><h4 id="usercontroller-2" tabindex="-1">UserController <a class="header-anchor" href="#usercontroller-2" aria-label="Permalink to &quot;UserController&quot;">​</a></h4><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">GetMapping</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">me</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Result</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">me</span><span style="color:#89DDFF;">(){</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// TODO 获取当前登录的用户并返回</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//在拦截器中已经把用户信息放到UserHolder里面了</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">UserDTO</span><span style="color:#A6ACCD;"> user </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> UserHolder</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getUser</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> Result</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">ok</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">user</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><h3 id="验证测试" tabindex="-1">验证测试 <a class="header-anchor" href="#验证测试" aria-label="Permalink to &quot;验证测试&quot;">​</a></h3><h4 id="发送验证码-2" tabindex="-1">发送验证码 <a class="header-anchor" href="#发送验证码-2" aria-label="Permalink to &quot;发送验证码&quot;">​</a></h4><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2023.3.30/202305221639599.png" alt="image-20230522163905539" style="zoom:80%;"><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2023.3.30/202305221639664.png" alt="image-20230522163926614" style="zoom:80%;"><h4 id="登录测试" tabindex="-1">登录测试 <a class="header-anchor" href="#登录测试" aria-label="Permalink to &quot;登录测试&quot;">​</a></h4><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2023.3.30/202305221640981.png" alt="image-20230522164013921" style="zoom:80%;"><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2023.3.30/202305221640129.png" alt="image-20230522164049073" style="zoom:80%;"><h4 id="获取个人信息" tabindex="-1">获取个人信息 <a class="header-anchor" href="#获取个人信息" aria-label="Permalink to &quot;获取个人信息&quot;">​</a></h4><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2023.3.30/202305221643466.png" alt="image-20230522164325409" style="zoom:80%;"><h1 id="实战演练" tabindex="-1">实战演练 <a class="header-anchor" href="#实战演练" aria-label="Permalink to &quot;实战演练&quot;">​</a></h1><h2 id="后端搭建" tabindex="-1">后端搭建 <a class="header-anchor" href="#后端搭建" aria-label="Permalink to &quot;后端搭建&quot;">​</a></h2><h3 id="依赖坐标" tabindex="-1">依赖坐标 <a class="header-anchor" href="#依赖坐标" aria-label="Permalink to &quot;依赖坐标&quot;">​</a></h3><div class="language-xml"><button title="Copy Code" class="copy"></button><span class="lang">xml</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">dependencies</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">     </span><span style="color:#676E95;font-style:italic;">&lt;!-- spring-web --&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">org.springframework.boot</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">spring-boot-starter-web</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#676E95;font-style:italic;">&lt;!-- spring-boot-starter-security --&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">org.springframework.boot</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">spring-boot-starter-security</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#676E95;font-style:italic;">&lt;!-- 热更新 --&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">org.springframework.boot</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">spring-boot-devtools</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">scope</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">runtime</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">scope</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">optional</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">true</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">optional</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#676E95;font-style:italic;">&lt;!-- mysql --&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">mysql</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">mysql-connector-java</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">scope</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">runtime</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">scope</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#676E95;font-style:italic;">&lt;!-- 连接池 --&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">com.alibaba</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">druid</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">version</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">1.1.10</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">version</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#676E95;font-style:italic;">&lt;!-- mybatis-plus --&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">com.baomidou</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">mybatis-plus-boot-starter</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">version</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">3.3.2</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">version</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#676E95;font-style:italic;">&lt;!-- fastjson --&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">com.alibaba</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">fastjson</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">version</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">1.2.40</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">version</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#676E95;font-style:italic;">&lt;!-- JWT --&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">com.auth0</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">java-jwt</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">version</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">3.2.0</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">version</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">io.jsonwebtoken</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">jjwt</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">version</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">0.9.1</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">version</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#676E95;font-style:italic;">&lt;!-- commons-io --&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">commons-io</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">commons-io</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">version</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">2.5</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">version</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">org.projectlombok</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">lombok</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">optional</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">true</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">optional</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#676E95;font-style:italic;">&lt;!-- spring boot redis 缓存引入 --&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">org.springframework.boot</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">spring-boot-starter-data-redis</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#676E95;font-style:italic;">&lt;!-- lettuce pool 缓存连接池 --&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">org.apache.commons</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">commons-pool2</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#676E95;font-style:italic;">&lt;!-- hutool工具类--&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">cn.hutool</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">hutool-all</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">version</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">5.3.3</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">version</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">dependencies</span><span style="color:#89DDFF;">&gt;</span></span></code></pre></div><h3 id="配置文件" tabindex="-1">配置文件 <a class="header-anchor" href="#配置文件" aria-label="Permalink to &quot;配置文件&quot;">​</a></h3><div class="language-yml"><button title="Copy Code" class="copy"></button><span class="lang">yml</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#F07178;">server</span><span style="color:#89DDFF;">:</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F07178;">port</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">8888</span></span>
<span class="line"><span style="color:#89DDFF;">  </span><span style="color:#676E95;font-style:italic;"># 不配置时，默认为 / ，如：localhost:8080/xxxxxx</span></span>
<span class="line"><span style="color:#89DDFF;">  </span><span style="color:#676E95;font-style:italic;"># 有配置时，比如 /demo，此时的访问方式为localhost:8080/demo/xxxxxx</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F07178;">servlet</span><span style="color:#89DDFF;">:</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#F07178;">context-path</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">/</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F07178;">spring</span><span style="color:#89DDFF;">:</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F07178;">datasource</span><span style="color:#89DDFF;">:</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#F07178;">type</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">com.alibaba.druid.pool.DruidDataSource</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#F07178;">driver-class-name</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">com.mysql.cj.jdbc.Driver</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#F07178;">url</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">jdbc:mysql://localhost:3306/xue?serverTimezone=Asia/Shanghai</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#F07178;">username</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">root</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#F07178;">password</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">123456</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F07178;">redis</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;"># redis配置</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#F07178;">host</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">127.0.0.1</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;"># IP</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#F07178;">port</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">6379</span><span style="color:#A6ACCD;">  </span><span style="color:#676E95;font-style:italic;"># 端口</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;"># password:  # 密码</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#F07178;">connect-timeout</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">10s</span><span style="color:#A6ACCD;">  </span><span style="color:#676E95;font-style:italic;"># 连接超时时间</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#F07178;">lettuce</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;"># lettuce redis客户端配置</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#F07178;">pool</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;"># 连接池配置</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#F07178;">max-active</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">8</span><span style="color:#A6ACCD;">  </span><span style="color:#676E95;font-style:italic;"># 连接池最大连接数（使用负值表示没有限制） 默认 8</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#F07178;">max-wait</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">200s</span><span style="color:#A6ACCD;">  </span><span style="color:#676E95;font-style:italic;"># 连接池最大阻塞等待时间（使用负值表示没有限制） 默认 -1</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#F07178;">max-idle</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">8</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;"># 连接池中的最大空闲连接 默认 8</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#F07178;">min-idle</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;"># 连接池中的最小空闲连接 默认 0</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F07178;">mybatis-plus</span><span style="color:#89DDFF;">:</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F07178;">global-config</span><span style="color:#89DDFF;">:</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#F07178;">db-config</span><span style="color:#89DDFF;">:</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#F07178;">id-type</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">auto</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F07178;">configuration</span><span style="color:#89DDFF;">:</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#F07178;">map-underscore-to-camel-case</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#FF9CAC;">true</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#F07178;">auto-mapping-behavior</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">full</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#F07178;">log-impl</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">org.apache.ibatis.logging.stdout.StdOutImpl</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F07178;">mapper-locations</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">classpath:mapper/*.xml</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F07178;">avatarImagesFilePath</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">H://java1234-vue3-admin3//pic</span></span></code></pre></div><h3 id="mybatisx" tabindex="-1">MybatisX <a class="header-anchor" href="#mybatisx" aria-label="Permalink to &quot;MybatisX&quot;">​</a></h3><blockquote><p>使用MybatisX进行代码生成</p></blockquote><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2023.3.30/202305222010014.png" alt="image-20230522201046953" style="zoom:80%;"><blockquote><p>先连接数据库</p></blockquote><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2023.3.30/202305222011075.png" alt="image-20230522201139015" style="zoom:80%;"><blockquote><p>再进行代码生成</p></blockquote><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2023.3.30/202305222012240.png" alt="image-20230522201212172" style="zoom:80%;"><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2023.3.30/202305222013790.png" alt="image-20230522201315715" style="zoom:80%;"><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2023.3.30/202305222013706.png" alt="image-20230522201356616" style="zoom:80%;"><h3 id="启动类" tabindex="-1">启动类 <a class="header-anchor" href="#启动类" aria-label="Permalink to &quot;启动类&quot;">​</a></h3><blockquote><p>要加上@MapperScan，进行包扫描</p></blockquote><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">SpringBootApplication</span></span>
<span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">MapperScan</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">com.java1234.mapper</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">Java1234Admin3Application</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">void</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">main</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">String</span><span style="color:#89DDFF;">[]</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">args</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">        SpringApplication</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">run</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">Java1234Admin3Application</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">class</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> args</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><h3 id="统一返回结果-1" tabindex="-1">统一返回结果 <a class="header-anchor" href="#统一返回结果-1" aria-label="Permalink to &quot;统一返回结果&quot;">​</a></h3><blockquote><p>项目中我们会将响应封装成json返回，一般我们会将所有接口的数据格式统一， 使前端(iOS Android, Web)对数据的操作更一致、轻松。一般情况下，统一返回数据格式没有固定的格式，只要能描述清楚返回的数据状态以及要返回的具体数据就可以。但是一般会包含状态码、返回消息、数据这几部分内容</p></blockquote><h4 id="返回格式" tabindex="-1">返回格式 <a class="header-anchor" href="#返回格式" aria-label="Permalink to &quot;返回格式&quot;">​</a></h4><blockquote><p>包含信息：状态码、信息、数据</p></blockquote><p>例如，我们的系统要求返回的基本数据格式如下：</p><p><strong>列表：</strong></p><div class="language-json"><button title="Copy Code" class="copy"></button><span class="lang">json</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C792EA;">code</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">200</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C792EA;">message</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">成功</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C792EA;">data</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">[</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">&quot;</span><span style="color:#FFCB6B;">id</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">2</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">&quot;</span><span style="color:#FFCB6B;">roleName</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">系统管理员</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">],</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C792EA;">ok</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">true</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><p><strong>分页：</strong></p><div class="language-json"><button title="Copy Code" class="copy"></button><span class="lang">json</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C792EA;">code</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">200</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C792EA;">message</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">成功</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C792EA;">data</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&quot;</span><span style="color:#FFCB6B;">records</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">[</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&quot;</span><span style="color:#F78C6C;">id</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">2</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&quot;</span><span style="color:#F78C6C;">roleName</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">系统管理员</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">},</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&quot;</span><span style="color:#F78C6C;">id</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">3</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&quot;</span><span style="color:#F78C6C;">name</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">普通管理员</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">],</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&quot;</span><span style="color:#FFCB6B;">total</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">10</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&quot;</span><span style="color:#FFCB6B;">size</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">3</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&quot;</span><span style="color:#FFCB6B;">current</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&quot;</span><span style="color:#FFCB6B;">orders</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">[],</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&quot;</span><span style="color:#FFCB6B;">hitCount</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">false,</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&quot;</span><span style="color:#FFCB6B;">searchCount</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">true,</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&quot;</span><span style="color:#FFCB6B;">pages</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">2</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">},</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C792EA;">ok</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">true</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><p><strong>没有返回数据：</strong></p><div class="language-json"><button title="Copy Code" class="copy"></button><span class="lang">json</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C792EA;">code</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">200</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C792EA;">message</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">成功</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C792EA;">data</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">null,</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C792EA;">ok</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">true</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><p><strong>失败：</strong></p><div class="language-json"><button title="Copy Code" class="copy"></button><span class="lang">json</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C792EA;">code</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">201</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C792EA;">message</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">失败</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C792EA;">data</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">null,</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C792EA;">ok</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">false</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><h4 id="枚举类" tabindex="-1">枚举类 <a class="header-anchor" href="#枚举类" aria-label="Permalink to &quot;枚举类&quot;">​</a></h4><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2023.3.30/202305161109709.png" alt="image-20230516110911643" style="zoom:80%;"><blockquote><p>操作模块：common-util，后续其他模块也会用到，故抽取到common-util模块</p><p>创建文件：com.atguigu.common.result.ResultCodeEnum</p></blockquote><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#F78C6C;">package</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">com</span><span style="color:#89DDFF;">.</span><span style="color:#C792EA;">atguigu</span><span style="color:#89DDFF;">.</span><span style="color:#C792EA;">common</span><span style="color:#89DDFF;">.</span><span style="color:#C792EA;">result</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F78C6C;">import</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">lombok</span><span style="color:#89DDFF;">.</span><span style="color:#C792EA;">Getter</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 统一返回结果状态信息类</span></span>
<span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Getter</span></span>
<span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">enum</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">ResultCodeEnum</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 定义枚举</span></span>
<span class="line"><span style="color:#A6ACCD;">    SUCCESS</span><span style="color:#89DDFF;">(</span><span style="color:#F78C6C;">200</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">成功</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">),</span></span>
<span class="line"><span style="color:#A6ACCD;">    FAIL</span><span style="color:#89DDFF;">(</span><span style="color:#F78C6C;">201</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">失败</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">),</span></span>
<span class="line"><span style="color:#A6ACCD;">    SERVICE_ERROR</span><span style="color:#89DDFF;">(</span><span style="color:#F78C6C;">2012</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">服务异常</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">),</span></span>
<span class="line"><span style="color:#A6ACCD;">    DATA_ERROR</span><span style="color:#89DDFF;">(</span><span style="color:#F78C6C;">204</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">数据异常</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">),</span></span>
<span class="line"><span style="color:#A6ACCD;">    LOGIN_AUTH</span><span style="color:#89DDFF;">(</span><span style="color:#F78C6C;">208</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">未登陆</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">),</span></span>
<span class="line"><span style="color:#A6ACCD;">    PERMISSION</span><span style="color:#89DDFF;">(</span><span style="color:#F78C6C;">209</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">没有权限</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 设置code和message</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Integer</span><span style="color:#A6ACCD;"> code</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> message</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 设置有参构造，目的是传递参数</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">ResultCodeEnum</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">Integer</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">code</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">message</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">this.</span><span style="color:#A6ACCD;">code </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> code</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">this.</span><span style="color:#A6ACCD;">message </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> message</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><h4 id="统一返回结果⭐" tabindex="-1">统一返回结果⭐ <a class="header-anchor" href="#统一返回结果⭐" aria-label="Permalink to &quot;统一返回结果⭐&quot;">​</a></h4><blockquote><p>创建文件：com.atguigu.common.result.Result</p></blockquote><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// 全局统一返回结果类</span></span>
<span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Data</span></span>
<span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">Result</span><span style="color:#89DDFF;">&lt;</span><span style="color:#C792EA;">T</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//返回码</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Integer</span><span style="color:#A6ACCD;"> code</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//返回消息</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> message</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//返回数据</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">T</span><span style="color:#A6ACCD;"> data</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">Result</span><span style="color:#89DDFF;">(){}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&lt;</span><span style="color:#C792EA;">T</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Result</span><span style="color:#89DDFF;">&lt;</span><span style="color:#C792EA;">T</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">build</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">T</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">body</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">ResultCodeEnum</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">resultCodeEnum</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">Result</span><span style="color:#89DDFF;">&lt;</span><span style="color:#C792EA;">T</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> result </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;font-style:italic;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Result</span><span style="color:#89DDFF;">&lt;</span><span style="color:#C792EA;">T</span><span style="color:#89DDFF;">&gt;();</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">// 封装数据</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">body </span><span style="color:#89DDFF;">!=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">null)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">            result</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setData</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">body</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">// 状态码</span></span>
<span class="line"><span style="color:#A6ACCD;">        result</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setCode</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">resultCodeEnum</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getCode</span><span style="color:#89DDFF;">());</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">// 返回信息</span></span>
<span class="line"><span style="color:#A6ACCD;">        result</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setMessage</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">resultCodeEnum</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getMessage</span><span style="color:#89DDFF;">());</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> result</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#89DDFF;">&lt;</span><span style="color:#C792EA;">T</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Result</span><span style="color:#89DDFF;">&lt;</span><span style="color:#C792EA;">T</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">ok</span><span style="color:#89DDFF;">(){</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">build</span><span style="color:#89DDFF;">(null,</span><span style="color:#A6ACCD;">ResultCodeEnum</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">SUCCESS</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 操作成功</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#89DDFF;">&lt;</span><span style="color:#C792EA;">T</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Result</span><span style="color:#89DDFF;">&lt;</span><span style="color:#C792EA;">T</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">ok</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">T</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">data</span><span style="color:#89DDFF;">){</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">build</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">data</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> ResultCodeEnum</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">SUCCESS</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#89DDFF;">&lt;</span><span style="color:#C792EA;">T</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Result</span><span style="color:#89DDFF;">&lt;</span><span style="color:#C792EA;">T</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">fail</span><span style="color:#89DDFF;">(){</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">build</span><span style="color:#89DDFF;">(null,</span><span style="color:#A6ACCD;">ResultCodeEnum</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">FAIL</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 操作失败</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#89DDFF;">&lt;</span><span style="color:#C792EA;">T</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Result</span><span style="color:#89DDFF;">&lt;</span><span style="color:#C792EA;">T</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">fail</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">T</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">data</span><span style="color:#89DDFF;">){</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">build</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">data</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> ResultCodeEnum</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">FAIL</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Result</span><span style="color:#89DDFF;">&lt;</span><span style="color:#C792EA;">T</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">message</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">msg</span><span style="color:#89DDFF;">){</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">this.</span><span style="color:#82AAFF;">setMessage</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">msg</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">this;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Result</span><span style="color:#89DDFF;">&lt;</span><span style="color:#C792EA;">T</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">code</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">Integer</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">code</span><span style="color:#89DDFF;">){</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">this.</span><span style="color:#82AAFF;">setCode</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">code</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">this;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><p>统一返回结果状态信息类下面的状态后续都会用到，所以直接引入了</p><h3 id="sysusercontroller" tabindex="-1">SysUserController <a class="header-anchor" href="#sysusercontroller" aria-label="Permalink to &quot;SysUserController&quot;">​</a></h3><blockquote><p>进行查询测试</p></blockquote><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">RestController</span></span>
<span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">RequestMapping</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/sys/user</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">SysUserController</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Autowired</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">SysUserService</span><span style="color:#A6ACCD;"> sysUserService</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">GetMapping</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">list1</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Result</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">getList</span><span style="color:#89DDFF;">(){</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">List</span><span style="color:#89DDFF;">&lt;</span><span style="color:#C792EA;">SysUser</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> list </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> sysUserService</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">list</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> Result</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">ok</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">list</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><h2 id="前端搭建" tabindex="-1">前端搭建 <a class="header-anchor" href="#前端搭建" aria-label="Permalink to &quot;前端搭建&quot;">​</a></h2><blockquote><p>我们用vue ui来搭建vue项目；vue ui是一个可视化图形界面，方便你去创建、更新和管理vue项目，包括下载router，vuex，axios，elementui等插件，配置好一些属性以及依赖关系，方便我们使用，我个人第一次接触它就感觉非常非常非常智能和强大。</p></blockquote><h3 id="安装vue-cli" tabindex="-1">安装Vue-cli <a class="header-anchor" href="#安装vue-cli" aria-label="Permalink to &quot;安装Vue-cli&quot;">​</a></h3><blockquote><p>vue-cli 是一个官方发布 vue.js 项目脚手架，使用 vue-cli 可以快速创建 vue 项目。因为vue ui是在Vue CLI基础上封装的</p></blockquote><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#FFCB6B;">npm</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">install</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-g</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">@vue/cli</span></span>
<span class="line"><span style="color:#FFCB6B;">vue</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">ui</span></span></code></pre></div><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2023.3.30/202305222035275.png" alt="image-20230522203500188" style="zoom:80%;"><h3 id="搭建项目" tabindex="-1">搭建项目 <a class="header-anchor" href="#搭建项目" aria-label="Permalink to &quot;搭建项目&quot;">​</a></h3><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2023.3.30/202305222041374.png" alt="image-20230522204123298" style="zoom:80%;"><blockquote><p>创建、导入、或管理项目</p></blockquote><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2023.3.30/202305222042973.png" alt="image-20230522204236879" style="zoom:80%;"><h3 id="自定义仪表盘" tabindex="-1">自定义仪表盘 <a class="header-anchor" href="#自定义仪表盘" aria-label="Permalink to &quot;自定义仪表盘&quot;">​</a></h3><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2023.3.30/202305222045689.png" alt="image-20230522204528580" style="zoom:80%;"><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2023.3.30/202305222045151.png" alt="image-20230522204550084" style="zoom:80%;"><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2023.3.30/202305222046425.png" alt="image-20230522204616296" style="zoom:80%;"><h3 id="安装axios-element-plus" tabindex="-1">安装axios element-plus <a class="header-anchor" href="#安装axios-element-plus" aria-label="Permalink to &quot;安装axios element-plus&quot;">​</a></h3><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2023.3.30/202305222035361.png" alt="image-20230522203539269" style="zoom:80%;"><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2023.3.30/202305222036679.png" alt="image-20230522203636602" style="zoom:80%;"><blockquote><p>Element-plus官网：<a href="https://element-plus.gitee.io/" target="_blank" rel="noreferrer">https://element-plus.gitee.io/</a></p></blockquote><h3 id="项目测试" tabindex="-1">项目测试 <a class="header-anchor" href="#项目测试" aria-label="Permalink to &quot;项目测试&quot;">​</a></h3><blockquote><p>导入elementplus以及样式</p></blockquote><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> ElementPlus </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">element-plus</span><span style="color:#89DDFF;">&#39;</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">element-plus/dist/index.css</span><span style="color:#89DDFF;">&#39;</span></span>
<span class="line"><span style="color:#82AAFF;">createApp</span><span style="color:#A6ACCD;">(App)</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">use</span><span style="color:#A6ACCD;">(store)</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">use</span><span style="color:#A6ACCD;">(router)</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">use</span><span style="color:#A6ACCD;">(ElementPlus)</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">mount</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">#app</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;">)</span></span></code></pre></div><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2023.3.30/202305222038987.png" alt="image-20230522203841909" style="zoom:80%;"><h1 id="jwt前后端交互" tabindex="-1">JWT前后端交互 <a class="header-anchor" href="#jwt前后端交互" aria-label="Permalink to &quot;JWT前后端交互&quot;">​</a></h1><blockquote><p>Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准；JWT就是一段字符串，用来进行用户身份认证的凭证，该字符串分成三段【头部、载荷、签证】</p></blockquote><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2023.3.30/202305222048446.png" alt="image-20230522204800349" style="zoom:80%;"><h2 id="后端实现" tabindex="-1">后端实现 <a class="header-anchor" href="#后端实现" aria-label="Permalink to &quot;后端实现&quot;">​</a></h2><h3 id="jwt工具类" tabindex="-1">JWT工具类 <a class="header-anchor" href="#jwt工具类" aria-label="Permalink to &quot;JWT工具类&quot;">​</a></h3><blockquote><p>constant/JwtConstant</p></blockquote><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">JwtConstant</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// token</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">final</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">int</span><span style="color:#A6ACCD;"> JWT_ERRCODE_NULL </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">4000</span><span style="color:#89DDFF;">;</span><span style="color:#A6ACCD;">         </span><span style="color:#676E95;font-style:italic;">//Token不存在</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">final</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">int</span><span style="color:#A6ACCD;"> JWT_ERRCODE_EXPIRE </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">4001</span><span style="color:#89DDFF;">;</span><span style="color:#A6ACCD;">       </span><span style="color:#676E95;font-style:italic;">//Token过期</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">final</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">int</span><span style="color:#A6ACCD;"> JWT_ERRCODE_FAIL </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">4002</span><span style="color:#89DDFF;">;</span><span style="color:#A6ACCD;">         </span><span style="color:#676E95;font-style:italic;">//验证不通过</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//JWT密匙，可以任意设置</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">final</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> JWT_SECERT </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">8677df7fc3a34e26a61c034d5ec8245d</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">;</span><span style="color:#A6ACCD;">  </span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//JWT有效时间：24小时</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">final</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">long</span><span style="color:#A6ACCD;"> JWT_TTL </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">24</span><span style="color:#89DDFF;">*</span><span style="color:#F78C6C;">60</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">*</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">60</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">*</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1000</span><span style="color:#89DDFF;">;</span><span style="color:#A6ACCD;">                          </span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><blockquote><p>result/CheckResult</p></blockquote><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Data</span></span>
<span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">CheckResult</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 映射运行结果：jwt验证信息</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">int</span><span style="color:#A6ACCD;"> errCode</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">boolean</span><span style="color:#A6ACCD;"> success</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Claims</span><span style="color:#A6ACCD;"> claims</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><blockquote><p>utils/JwtUtils</p></blockquote><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">JwtUtils</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 签发JWT，可以是JSON数据 尽可能少</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">createJWT</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">id</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">subject</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">long</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">ttlMillis</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">SignatureAlgorithm</span><span style="color:#A6ACCD;"> signatureAlgorithm </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> SignatureAlgorithm</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">HS256</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">long</span><span style="color:#A6ACCD;"> nowMillis </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> System</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">currentTimeMillis</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">Date</span><span style="color:#A6ACCD;"> now </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">Date</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">nowMillis</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">SecretKey</span><span style="color:#A6ACCD;"> secretKey </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">generalKey</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">JwtBuilder</span><span style="color:#A6ACCD;"> builder </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> Jwts</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">builder</span><span style="color:#89DDFF;">()</span></span>
<span class="line"><span style="color:#A6ACCD;">                </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setId</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">id</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">                </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setSubject</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">subject</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;">   </span><span style="color:#676E95;font-style:italic;">// 主题</span></span>
<span class="line"><span style="color:#A6ACCD;">                </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setIssuer</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">Java1234</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;">     </span><span style="color:#676E95;font-style:italic;">// 签发者</span></span>
<span class="line"><span style="color:#A6ACCD;">                </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setIssuedAt</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">now</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;">      </span><span style="color:#676E95;font-style:italic;">// 签发时间</span></span>
<span class="line"><span style="color:#A6ACCD;">                </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">signWith</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">signatureAlgorithm</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> secretKey</span><span style="color:#89DDFF;">);</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">// 签名算法以及密匙</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">ttlMillis </span><span style="color:#89DDFF;">&gt;=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#C792EA;">long</span><span style="color:#A6ACCD;"> expMillis </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> nowMillis </span><span style="color:#89DDFF;">+</span><span style="color:#A6ACCD;"> ttlMillis</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#C792EA;">Date</span><span style="color:#A6ACCD;"> expDate </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">Date</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">expMillis</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">            builder</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setExpiration</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">expDate</span><span style="color:#89DDFF;">);</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">// 过期时间</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> builder</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">compact</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 生成jwt token</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">genJwtToken</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">username</span><span style="color:#89DDFF;">){</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">createJWT</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">username</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;">username</span><span style="color:#89DDFF;">,</span><span style="color:#F78C6C;">60</span><span style="color:#89DDFF;">*</span><span style="color:#F78C6C;">60</span><span style="color:#89DDFF;">*</span><span style="color:#F78C6C;">1000</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 验证JWT</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">CheckResult</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">validateJWT</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">jwtStr</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">CheckResult</span><span style="color:#A6ACCD;"> checkResult </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">CheckResult</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">Claims</span><span style="color:#A6ACCD;"> claims </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">null;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">try</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">            claims </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">parseJWT</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">jwtStr</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">            checkResult</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setSuccess</span><span style="color:#89DDFF;">(true);</span></span>
<span class="line"><span style="color:#A6ACCD;">            checkResult</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setClaims</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">claims</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">catch</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">ExpiredJwtException</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">e</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">            checkResult</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setErrCode</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">JwtConstant</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">JWT_ERRCODE_EXPIRE</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">            checkResult</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setSuccess</span><span style="color:#89DDFF;">(false);</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">catch</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">SignatureException</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">e</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">            checkResult</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setErrCode</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">JwtConstant</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">JWT_ERRCODE_FAIL</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">            checkResult</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setSuccess</span><span style="color:#89DDFF;">(false);</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">catch</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">Exception</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">e</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">            checkResult</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setErrCode</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">JwtConstant</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">JWT_ERRCODE_FAIL</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">            checkResult</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setSuccess</span><span style="color:#89DDFF;">(false);</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> checkResult</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 生成加密Key</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">SecretKey</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">generalKey</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">byte</span><span style="color:#89DDFF;">[]</span><span style="color:#A6ACCD;"> encodedKey </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> Base64</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">decode</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">JwtConstant</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">JWT_SECERT</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">SecretKey</span><span style="color:#A6ACCD;"> key </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">SecretKeySpec</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">encodedKey</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> encodedKey</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">length</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">AES</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> key</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 解析JWT字符串</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Claims</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">parseJWT</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">jwt</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">SecretKey</span><span style="color:#A6ACCD;"> secretKey </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">generalKey</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> Jwts</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">parser</span><span style="color:#89DDFF;">()</span></span>
<span class="line"><span style="color:#A6ACCD;">                </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setSigningKey</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">secretKey</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">                </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">parseClaimsJws</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">jwt</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">                </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getBody</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">void</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">main</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">String</span><span style="color:#89DDFF;">[]</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">args</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">throws</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">InterruptedException</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">//小明失效 10s</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> sc </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">createJWT</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">1</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">小明</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">60</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">*</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">60</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">*</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1000</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">        System</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">out</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">println</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">sc</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">        System</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">out</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">println</span><span style="color:#89DDFF;">(</span><span style="color:#82AAFF;">validateJWT</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">sc</span><span style="color:#89DDFF;">).</span><span style="color:#82AAFF;">getErrCode</span><span style="color:#89DDFF;">());</span></span>
<span class="line"><span style="color:#A6ACCD;">        System</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">out</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">println</span><span style="color:#89DDFF;">(</span><span style="color:#82AAFF;">validateJWT</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">sc</span><span style="color:#89DDFF;">).</span><span style="color:#82AAFF;">getClaims</span><span style="color:#89DDFF;">().</span><span style="color:#82AAFF;">getId</span><span style="color:#89DDFF;">());</span></span>
<span class="line"><span style="color:#A6ACCD;">        System</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">out</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">println</span><span style="color:#89DDFF;">(</span><span style="color:#82AAFF;">validateJWT</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">sc</span><span style="color:#89DDFF;">).</span><span style="color:#82AAFF;">getClaims</span><span style="color:#89DDFF;">().</span><span style="color:#82AAFF;">getSubject</span><span style="color:#89DDFF;">());</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">//Thread.sleep(3000);</span></span>
<span class="line"><span style="color:#A6ACCD;">        System</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">out</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">println</span><span style="color:#89DDFF;">(</span><span style="color:#82AAFF;">validateJWT</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">sc</span><span style="color:#89DDFF;">).</span><span style="color:#82AAFF;">getClaims</span><span style="color:#89DDFF;">());</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">Claims</span><span style="color:#A6ACCD;"> claims </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">validateJWT</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">sc</span><span style="color:#89DDFF;">).</span><span style="color:#82AAFF;">getClaims</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> sc2 </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">createJWT</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">claims</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getId</span><span style="color:#89DDFF;">(),</span><span style="color:#A6ACCD;">claims</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getSubject</span><span style="color:#89DDFF;">(),</span><span style="color:#A6ACCD;"> JwtConstant</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">JWT_TTL</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">        System</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">out</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">println</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">sc2</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2023.3.30/202305222052932.png" alt="image-20230522205214855" style="zoom:80%;"><h3 id="testcontroller" tabindex="-1">TestController <a class="header-anchor" href="#testcontroller" aria-label="Permalink to &quot;TestController&quot;">​</a></h3><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">RestController</span></span>
<span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">RequestMapping</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/test</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">TestController</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Autowired</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">SysUserService</span><span style="color:#A6ACCD;"> sysUserService</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">GetMapping</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/user/list</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Result</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">userList</span><span style="color:#89DDFF;">(@</span><span style="color:#C792EA;">RequestHeader</span><span style="color:#89DDFF;">(</span><span style="color:#FFCB6B;">required</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">false)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">token</span><span style="color:#89DDFF;">){</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#89DDFF;">(!</span><span style="color:#A6ACCD;">StringUtils</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">isEmpty</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">token</span><span style="color:#89DDFF;">)){</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#C792EA;">List</span><span style="color:#89DDFF;">&lt;</span><span style="color:#C792EA;">SysUser</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> userList </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> sysUserService</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">list</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> Result</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">ok</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">userList</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">}</span><span style="color:#89DDFF;font-style:italic;">else</span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> Result</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">fail</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">没有权限访问</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">GetMapping</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/login</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Result</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">login</span><span style="color:#89DDFF;">(){</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> token </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> JwtUtils</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">genJwtToken</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">java1234</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> Result</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">ok</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">token</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><h3 id="跨域访问" tabindex="-1">跨域访问 <a class="header-anchor" href="#跨域访问" aria-label="Permalink to &quot;跨域访问&quot;">​</a></h3><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Configuration</span></span>
<span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">WebAppConfigurer</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">implements</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">WebMvcConfigurer</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Override</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">void</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">addCorsMappings</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">CorsRegistry</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">registry</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">        registry</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">addMapping</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/**</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">                </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">allowedOrigins</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">*</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">                </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">allowCredentials</span><span style="color:#89DDFF;">(true)</span></span>
<span class="line"><span style="color:#A6ACCD;">                </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">allowedMethods</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">GET</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">HEAD</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">POST</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">PUT</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">DELETE</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">OPTIONS</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">                </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">maxAge</span><span style="color:#89DDFF;">(</span><span style="color:#F78C6C;">3600</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><h3 id="访问测试-1" tabindex="-1">访问测试 <a class="header-anchor" href="#访问测试-1" aria-label="Permalink to &quot;访问测试&quot;">​</a></h3><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2023.3.30/202305222107129.png" alt="image-20230522210717060" style="zoom:80%;"><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2023.3.30/202305222115742.png" alt="image-20230522211551681" style="zoom:80%;"><h2 id="前端实现" tabindex="-1">前端实现 <a class="header-anchor" href="#前端实现" aria-label="Permalink to &quot;前端实现&quot;">​</a></h2><h3 id="utils-request-js" tabindex="-1">utils/request.js <a class="header-anchor" href="#utils-request-js" aria-label="Permalink to &quot;utils/request.js&quot;">​</a></h3><blockquote><p>utils/request.js</p></blockquote><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// 引入axios</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> axios </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">axios</span><span style="color:#89DDFF;">&#39;</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> store </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">@/store</span><span style="color:#89DDFF;">&#39;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> baseUrl</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">:8888/</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 创建axios实例</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> httpService </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> axios</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">create</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// url前缀-&#39;http:xxx.xxx&#39;</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// baseURL: p<wbr>rocess.env.BASE_API, // 需自定义</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#F07178;">baseURL</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;">baseUrl</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 请求超时时间</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#F07178;">timeout</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">3000</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">// 需自定义</span></span>
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">//添加请求和响应拦截器</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 添加请求拦截器</span></span>
<span class="line"><span style="color:#A6ACCD;">httpService</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">interceptors</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">request</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">use</span><span style="color:#A6ACCD;">(</span><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">config</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 在发送请求之前做些什么，保存token</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">//config.headers.token=window.sessionStorage.getItem(&#39;token&#39;);</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">store=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">+</span><span style="color:#A6ACCD;">store</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">getters</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">GET_TOKEN</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">config</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">headers</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">token</span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;">store</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">getters</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">GET_TOKEN</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">config</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">},</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">error</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 对请求错误做些什么</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#FFCB6B;">Promise</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">reject</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">error</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 添加响应拦截器</span></span>
<span class="line"><span style="color:#A6ACCD;">httpService</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">interceptors</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">response</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">use</span><span style="color:#A6ACCD;">(</span><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">response</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 对响应数据做点什么</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">response</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">},</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">error</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 对响应错误做点什么</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#FFCB6B;">Promise</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">reject</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">error</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">/*网络请求部分*/</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// get请求、url:请求地址、params:参数</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">get</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">url</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">params</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{})</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">new</span><span style="color:#F07178;"> </span><span style="color:#FFCB6B;">Promise</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">resolve</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;font-style:italic;">reject</span><span style="color:#89DDFF;">)</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#82AAFF;">httpService</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">            url</span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">url</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#F07178;">            method</span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">get</span><span style="color:#89DDFF;">&#39;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#F07178;">            params</span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">params</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">then</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;font-style:italic;">response</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">            </span><span style="color:#82AAFF;">resolve</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">response</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">catch</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;font-style:italic;">error</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">            </span><span style="color:#82AAFF;">reject</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">error</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// post请求、url:请求地址、params:参数</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">post</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">url</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">params</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{})</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">new</span><span style="color:#F07178;"> </span><span style="color:#FFCB6B;">Promise</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">resolve</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;font-style:italic;">reject</span><span style="color:#89DDFF;">)</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#82AAFF;">httpService</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">            url</span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">url</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#F07178;">            method</span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">post</span><span style="color:#89DDFF;">&#39;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#F07178;">            data</span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">params</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">then</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;font-style:italic;">response</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">            </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">response</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">            </span><span style="color:#82AAFF;">resolve</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">response</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">catch</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;font-style:italic;">error</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">            </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">error</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">            </span><span style="color:#82AAFF;">reject</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">error</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 文件上传</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">fileUpload</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">url</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">params</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{})</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">new</span><span style="color:#F07178;"> </span><span style="color:#FFCB6B;">Promise</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">resolve</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;font-style:italic;">reject</span><span style="color:#89DDFF;">)</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#82AAFF;">httpService</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">            url</span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">url</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#F07178;">            method</span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">post</span><span style="color:#89DDFF;">&#39;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#F07178;">            data</span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">params</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#F07178;">            headers</span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#F07178;">Content-Type</span><span style="color:#89DDFF;">&#39;</span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">multipart/form-data</span><span style="color:#89DDFF;">&#39;</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">then</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;font-style:italic;">response</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">            </span><span style="color:#82AAFF;">resolve</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">response</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">catch</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;font-style:italic;">error</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">            </span><span style="color:#82AAFF;">reject</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">error</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">getServerUrl</span><span style="color:#89DDFF;">(){</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">baseUrl</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">default</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">    get</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">    post</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">    fileUpload</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">    getServerUrl</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><h3 id="store-index-js" tabindex="-1">store/index.js <a class="header-anchor" href="#store-index-js" aria-label="Permalink to &quot;store/index.js&quot;">​</a></h3><blockquote><p>vuex</p></blockquote><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">createStore</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">vuex</span><span style="color:#89DDFF;">&#39;</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> router </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">@/router</span><span style="color:#89DDFF;">&#39;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">default</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">createStore</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F07178;">state</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">},</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F07178;">getters</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#82AAFF;">GET_TOKEN</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;font-style:italic;">state</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">sessionStorage</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getItem</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">token</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">},</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F07178;">mutations</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#82AAFF;">SET_TOKEN</span><span style="color:#89DDFF;">:(</span><span style="color:#A6ACCD;font-style:italic;">state</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;font-style:italic;">token</span><span style="color:#89DDFF;">)</span><span style="color:#C792EA;">=&gt;</span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#A6ACCD;">sessionStorage</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setItem</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">token</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;">token</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">},</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F07178;">actions</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">},</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F07178;">modules</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span></span></code></pre></div><h3 id="app-vue" tabindex="-1">App.vue <a class="header-anchor" href="#app-vue" aria-label="Permalink to &quot;App.vue&quot;">​</a></h3><div class="language-vue"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">template</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">el-button</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">type</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">primary</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">@click</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">handleLogin</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">测试登录</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">el-button</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">el-button</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">type</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">danger</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">@click</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">handleUserList</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">测试获取用户请求</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">el-button</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">template</span><span style="color:#89DDFF;">&gt;</span></span></code></pre></div><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">script</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">setup</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span></span>
<span class="line"><span style="color:#A6ACCD;">import requestUtil from &#39;@/util/request&#39;</span></span>
<span class="line"><span style="color:#A6ACCD;">import store from &#39;@/store&#39;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">const handleLogin = async ()=&gt;</span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  let result </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">await</span><span style="color:#A6ACCD;"> requestUtil</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">get</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/test/login</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">  let data </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> result</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">data;</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#82AAFF;">if</span><span style="color:#A6ACCD;">(data</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">code </span><span style="color:#89DDFF;">===</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">200</span><span style="color:#A6ACCD;">)</span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">    const token </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> data</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">data;</span></span>
<span class="line"><span style="color:#A6ACCD;">    console.log(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F07178;">登录成功：token=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F07178;">+token);</span></span>
<span class="line"><span style="color:#F07178;">    store.commit(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#F07178;">SET_TOKEN</span><span style="color:#89DDFF;">&#39;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;">token);</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">else</span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">    console.log(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F07178;">登录出错！</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F07178;">);</span></span>
<span class="line"><span style="color:#F07178;">  }</span></span>
<span class="line"><span style="color:#F07178;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F07178;">const handleUserList=async ()=&gt;{</span></span>
<span class="line"><span style="color:#F07178;">  let result = await requestUtil.get(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F07178;">test/user/list</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F07178;">);</span></span>
<span class="line"><span style="color:#F07178;">  let data = result.data;</span></span>
<span class="line"><span style="color:#F07178;">  if(data.code === 200){</span></span>
<span class="line"><span style="color:#F07178;">     const userList = data.data;</span></span>
<span class="line"><span style="color:#F07178;">     console.log(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F07178;">用户列表信息：userList=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F07178;">+userList);</span></span>
<span class="line"><span style="color:#F07178;">  }</span></span>
<span class="line"><span style="color:#F07178;">}</span></span>
<span class="line"><span style="color:#F07178;">&lt;/script&gt;</span></span></code></pre></div><h3 id="访问测试-2" tabindex="-1">访问测试 <a class="header-anchor" href="#访问测试-2" aria-label="Permalink to &quot;访问测试&quot;">​</a></h3><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2023.3.30/202305222203295.png" alt="image-20230522220304233" style="zoom:80%;"><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2023.3.30/202305222202746.png" alt="image-20230522220229657" style="zoom:80%;"><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2023.3.30/202305222206678.png" alt="image-20230522220612590" style="zoom:80%;"><h1 id="登录功能" tabindex="-1">登录功能 <a class="header-anchor" href="#登录功能" aria-label="Permalink to &quot;登录功能&quot;">​</a></h1><h2 id="前端样式" tabindex="-1">前端样式 <a class="header-anchor" href="#前端样式" aria-label="Permalink to &quot;前端样式&quot;">​</a></h2><h3 id="normalize-css" tabindex="-1">normalize.css <a class="header-anchor" href="#normalize-css" aria-label="Permalink to &quot;normalize.css&quot;">​</a></h3><blockquote><p>重置默认样式：<a href="http://necolas.github.io/normalize.css/" target="_blank" rel="noreferrer">http://necolas.github.io/normalize.css/</a></p></blockquote><blockquote><p>下载完成后，复制到styles/normalize.css，然后在main.js中导入即可</p></blockquote><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">@/assets/styles/normalize.css</span><span style="color:#89DDFF;">&#39;</span></span></code></pre></div><h3 id="app-vue-1" tabindex="-1">App.vue <a class="header-anchor" href="#app-vue-1" aria-label="Permalink to &quot;App.vue&quot;">​</a></h3><div class="language-vue"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">template</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">router-view</span><span style="color:#89DDFF;">/&gt;</span></span>
<span class="line"><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">template</span><span style="color:#89DDFF;">&gt;</span></span></code></pre></div><div class="language-css"><button title="Copy Code" class="copy"></button><span class="lang">css</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">&lt;</span><span style="color:#FFCB6B;">style</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#FFCB6B;">html</span><span style="color:#89DDFF;">,</span><span style="color:#FFCB6B;">body</span><span style="color:#89DDFF;">,#</span><span style="color:#F78C6C;">app</span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#B2CCD6;">height</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">100%</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">.</span><span style="color:#FFCB6B;">app-container</span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#B2CCD6;">padding</span><span style="color:#89DDFF;">:</span><span style="color:#F78C6C;">20px</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">&lt;/</span><span style="color:#FFCB6B;">style</span><span style="color:#89DDFF;">&gt;</span></span></code></pre></div><h3 id="router-index-js" tabindex="-1">router/index.js <a class="header-anchor" href="#router-index-js" aria-label="Permalink to &quot;router/index.js&quot;">​</a></h3><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">createRouter</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">createWebHashHistory</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">vue-router</span><span style="color:#89DDFF;">&#39;</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> routes </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> [</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#F07178;">path</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">/</span><span style="color:#89DDFF;">&#39;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#F07178;">name</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">首页</span><span style="color:#89DDFF;">&#39;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#82AAFF;">component</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">import</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">../layout</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;">)</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#F07178;">redirect</span><span style="color:#89DDFF;">:</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">/index</span><span style="color:#89DDFF;">&#39;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#F07178;">children</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;">[</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#F07178;">path</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">/index</span><span style="color:#89DDFF;">&#39;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#F07178;">name</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">首页</span><span style="color:#89DDFF;">&#39;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#82AAFF;">component</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">import</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">../views/index/index</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">},</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#F07178;">path</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">/userCenter</span><span style="color:#89DDFF;">&#39;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#F07178;">name</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">个人中心</span><span style="color:#89DDFF;">&#39;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#82AAFF;">component</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">import</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">../views/userCenter/index</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">},</span></span>
<span class="line"><span style="color:#A6ACCD;">    ]</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">},</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#F07178;">path</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">/login</span><span style="color:#89DDFF;">&#39;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#F07178;">name</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">login</span><span style="color:#89DDFF;">&#39;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#82AAFF;">component</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">import</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">../views/Login.vue</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">]</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> router </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">createRouter</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F07178;">history</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">createWebHashHistory</span><span style="color:#A6ACCD;">()</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">  routes</span></span>
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">default</span><span style="color:#A6ACCD;"> router</span></span></code></pre></div><h3 id="sass" tabindex="-1">sass <a class="header-anchor" href="#sass" aria-label="Permalink to &quot;sass&quot;">​</a></h3><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#FFCB6B;">npm</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">install</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">sass-loader</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--save-dev</span></span>
<span class="line"><span style="color:#FFCB6B;">npm</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">install</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">sass</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--save-dev</span></span></code></pre></div><h3 id="login-vue" tabindex="-1">Login.vue <a class="header-anchor" href="#login-vue" aria-label="Permalink to &quot;Login.vue&quot;">​</a></h3><h4 id="静态页面结构" tabindex="-1">静态页面结构 <a class="header-anchor" href="#静态页面结构" aria-label="Permalink to &quot;静态页面结构&quot;">​</a></h4><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2023.3.30/202305231048919.png" alt="image-20230523104801658" style="zoom:80%;"><div class="language-vue"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">template</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">div</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">class</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">login</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#676E95;font-style:italic;">&lt;!-- 登录表单 --&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">el-form</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">ref</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">loginRef</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">:model</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">loginForm</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">:rules</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">loginRules</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">class</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">login-form</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">h3</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">class</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">title</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">Java1234 Vue3 后台管理系统</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">h3</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#676E95;font-style:italic;">&lt;!-- 账号输入框 --&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">el-form-item</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">prop</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">username</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">el-input</span></span>
<span class="line"><span style="color:#89DDFF;">            </span><span style="color:#C792EA;">v-model</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">loginForm.username</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#89DDFF;">            </span><span style="color:#C792EA;">type</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">text</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#89DDFF;">            </span><span style="color:#C792EA;">size</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">large</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#89DDFF;">            </span><span style="color:#C792EA;">auto-complete</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">off</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#89DDFF;">            </span><span style="color:#C792EA;">placeholder</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">账号</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">          </span><span style="color:#676E95;font-style:italic;">&lt;!-- iconfont图标 --&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">          </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">template</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">#</span><span style="color:#C792EA;">prefix</span><span style="color:#89DDFF;">&gt;&lt;</span><span style="color:#F07178;">span</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">class</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">iconfont icon-denglu</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">&gt;&lt;/</span><span style="color:#F07178;">span</span><span style="color:#89DDFF;">&gt;&lt;/</span><span style="color:#F07178;">template</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">el-input</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">el-form-item</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#676E95;font-style:italic;">&lt;!-- 密码输入框 --&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">el-form-item</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">prop</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">password</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">el-input</span></span>
<span class="line"><span style="color:#89DDFF;">             </span><span style="color:#C792EA;">v-model</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">loginForm.password</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#89DDFF;">            </span><span style="color:#C792EA;">type</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">password</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#89DDFF;">            </span><span style="color:#C792EA;">size</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">large</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#89DDFF;">            </span><span style="color:#C792EA;">auto-complete</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">off</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#89DDFF;">            </span><span style="color:#C792EA;">placeholder</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">密码</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#89DDFF;">            </span><span style="color:#C792EA;">@keyup.enter</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">handleLogin</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">          </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">template</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">#</span><span style="color:#C792EA;">prefix</span><span style="color:#89DDFF;">&gt;&lt;</span><span style="color:#F07178;">span</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">class</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">iconfont icon-denglu-mima</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">&gt;&lt;/</span><span style="color:#F07178;">span</span><span style="color:#89DDFF;">&gt;&lt;/</span><span style="color:#F07178;">template</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">el-input</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">el-form-item</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">	  </span><span style="color:#676E95;font-style:italic;">&lt;!-- 记住密码，即记住我 --&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">el-checkbox</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">v-model</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">loginForm.rememberMe</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;"> </span></span>
<span class="line"><span style="color:#89DDFF;">                   </span><span style="color:#C792EA;">style</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">margin:0px 0px 25px 0px;</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">记住密码</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">el-checkbox</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#676E95;font-style:italic;">&lt;!-- 登录按钮 --&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">el-form-item</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">style</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">width:100%;</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">el-button</span></span>
<span class="line"><span style="color:#89DDFF;">            </span><span style="color:#C792EA;">size</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">large</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#89DDFF;">            </span><span style="color:#C792EA;">type</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">primary</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#89DDFF;">            </span><span style="color:#C792EA;">style</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">width:100%;</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#89DDFF;">            </span><span style="color:#C792EA;">@click.prevent</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">handleLogin</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">          </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">span</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">登 录</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">span</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">el-button</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">el-form-item</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">el-form</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#676E95;font-style:italic;">&lt;!--  底部  --&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">div</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">class</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">el-login-footer</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">span</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">Copyright © 2013-2022 </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">a</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">href</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">http://www.java1234.vip</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;"> </span></span>
<span class="line"><span style="color:#89DDFF;">                                     </span><span style="color:#C792EA;">target</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">_blank</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">java1234.vip</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">a</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> 版权所有.</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">span</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">div</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">div</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">template</span><span style="color:#89DDFF;">&gt;</span></span></code></pre></div><h4 id="样式" tabindex="-1">样式 <a class="header-anchor" href="#样式" aria-label="Permalink to &quot;样式&quot;">​</a></h4><div class="language-css"><button title="Copy Code" class="copy"></button><span class="lang">css</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">&lt;</span><span style="color:#FFCB6B;">style</span><span style="color:#A6ACCD;"> lang=&quot;scss&quot; scoped</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#FFCB6B;">a</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#B2CCD6;">color</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;">white</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">.</span><span style="color:#FFCB6B;">login</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#B2CCD6;">display</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> flex</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#B2CCD6;">justify-content</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> center</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#B2CCD6;">align-items</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> center</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#B2CCD6;">height</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">100%</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#B2CCD6;">background-image</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">url</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">../assets/images/login-background.jpg</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#B2CCD6;">background-size</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> cover</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">.</span><span style="color:#FFCB6B;">title</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#B2CCD6;">margin</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0px</span><span style="color:#A6ACCD;"> auto </span><span style="color:#F78C6C;">30px</span><span style="color:#A6ACCD;"> auto</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#B2CCD6;">text-align</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> center</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#B2CCD6;">color</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">#</span><span style="color:#A6ACCD;">707070</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">.</span><span style="color:#FFCB6B;">login-form</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#B2CCD6;">border-radius</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">6px</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#B2CCD6;">background</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">#</span><span style="color:#A6ACCD;">ffffff</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#B2CCD6;">width</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">400px</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#B2CCD6;">padding</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">25px</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">25px</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">5px</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">25px</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">  .el-input {</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#B2CCD6;">height</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">40px</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">    input {</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#B2CCD6;">display</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> inline-block</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#B2CCD6;">height</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">40px</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">  }</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">.</span><span style="color:#FFCB6B;">input-icon</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#B2CCD6;">height</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">39px</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#B2CCD6;">width</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">14px</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#B2CCD6;">margin-left</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0px</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">}</span></span>
<span class="line"><span style="color:#89DDFF;">.</span><span style="color:#FFCB6B;">login-tip</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#B2CCD6;">font-size</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">13px</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#B2CCD6;">text-align</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> center</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#B2CCD6;">color</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">#</span><span style="color:#A6ACCD;">bfbfbf</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">.</span><span style="color:#FFCB6B;">login-code</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#B2CCD6;">width</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">33%</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#B2CCD6;">height</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">40px</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#B2CCD6;">float</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> right</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">  img {</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#B2CCD6;">cursor</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> pointer</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#B2CCD6;">vertical-align</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> middle</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">}</span></span>
<span class="line"><span style="color:#89DDFF;">.</span><span style="color:#FFCB6B;">el-login-footer</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#B2CCD6;">height</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">40px</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#B2CCD6;">line-height</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">40px</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#B2CCD6;">position</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> fixed</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#B2CCD6;">bottom</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#B2CCD6;">width</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">100%</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#B2CCD6;">text-align</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> center</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#B2CCD6;">color</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">#</span><span style="color:#A6ACCD;">fff</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#B2CCD6;">font-family</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> Arial</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#B2CCD6;">font-size</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">12px</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#B2CCD6;">letter-spacing</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1px</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">.</span><span style="color:#FFCB6B;">login-code-img</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#B2CCD6;">height</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">40px</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#B2CCD6;">padding-left</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">12px</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">&lt;/</span><span style="color:#FFCB6B;">style</span><span style="color:#89DDFF;">&gt;</span></span></code></pre></div><h2 id="后端配置⭐" tabindex="-1">后端配置⭐ <a class="header-anchor" href="#后端配置⭐" aria-label="Permalink to &quot;后端配置⭐&quot;">​</a></h2><h3 id="坐标依赖-1" tabindex="-1">坐标依赖 <a class="header-anchor" href="#坐标依赖-1" aria-label="Permalink to &quot;坐标依赖&quot;">​</a></h3><blockquote><p>前面已经加入了该依赖</p></blockquote><div class="language-xml"><button title="Copy Code" class="copy"></button><span class="lang">xml</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">org.springframework.boot</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">groupId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">spring-boot-starter-security</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">artifactId</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">dependency</span><span style="color:#89DDFF;">&gt;</span></span></code></pre></div><h3 id="securityconfig" tabindex="-1">SecurityConfig <a class="header-anchor" href="#securityconfig" aria-label="Permalink to &quot;SecurityConfig&quot;">​</a></h3><blockquote><p>config/SecurityConfig</p></blockquote><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Configuration</span></span>
<span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">EnableWebSecurity</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">// 开启Security</span></span>
<span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">EnableGlobalMethodSecurity</span><span style="color:#89DDFF;">(</span><span style="color:#FFCB6B;">prePostEnabled</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">true)</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">// 注解使用</span></span>
<span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">SecurityConfig</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">extends</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">WebSecurityConfigurerAdapter</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Autowired</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">LoginSuccessHandler</span><span style="color:#A6ACCD;"> loginSuccessHandler</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Autowired</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">LoginFailureHandler</span><span style="color:#A6ACCD;"> loginFailureHandler</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Autowired</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">JwtLogoutSuccessHandler</span><span style="color:#A6ACCD;"> jwtLogoutSuccessHandler</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Autowired</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">JwtAuthenticationEntryPoint</span><span style="color:#A6ACCD;"> jwtAuthenticationEntryPoint</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Autowired</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">MyUserDetailsServiceImpl</span><span style="color:#A6ACCD;"> myUserDetailsService</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">	</span><span style="color:#676E95;font-style:italic;">// 白名单放行数组</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">final</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> URL_WHITELIST</span><span style="color:#89DDFF;">[]</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">={</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/login</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/logout</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/captcha</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/password</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/image/**</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/test/**</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Bean</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">JwtAuthenticationFilter</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">jwtAuthenticationFilter</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">throws</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Exception</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">JwtAuthenticationFilter</span><span style="color:#A6ACCD;"> jwtAuthenticationFilter</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;font-style:italic;">new</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#82AAFF;">JwtAuthenticationFilter</span><span style="color:#89DDFF;">(</span><span style="color:#82AAFF;">authenticationManager</span><span style="color:#89DDFF;">());</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> jwtAuthenticationFilter</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Bean</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">BCryptPasswordEncoder</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">bCryptPasswordEncoder</span><span style="color:#89DDFF;">(){</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">BCryptPasswordEncoder</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Override</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">protected</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">void</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">configure</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">AuthenticationManagerBuilder</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">auth</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">throws</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Exception</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">        auth</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">userDetailsService</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">myUserDetailsService</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">	</span><span style="color:#676E95;font-style:italic;">// 核心配置</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Override</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">protected</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">void</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">configure</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">HttpSecurity</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">http</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">throws</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Exception</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">// 开启跨域 以及csrf攻击 关闭</span></span>
<span class="line"><span style="color:#A6ACCD;">        http</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">cors</span><span style="color:#89DDFF;">()</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">and</span><span style="color:#89DDFF;">()</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">csrf</span><span style="color:#89DDFF;">()</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">disable</span><span style="color:#89DDFF;">()</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">// 登录登出配置，登录页面和登出页面，失败页面</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">formLogin</span><span style="color:#89DDFF;">()</span></span>
<span class="line"><span style="color:#A6ACCD;">              </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">successHandler</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">loginSuccessHandler</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">              </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">failureHandler</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">loginFailureHandler</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">and</span><span style="color:#89DDFF;">()</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">logout</span><span style="color:#89DDFF;">()</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">logoutSuccessHandler</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">jwtLogoutSuccessHandler</span><span style="color:#89DDFF;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">// session禁用配置（前后端分离配置）</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">and</span><span style="color:#89DDFF;">()</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">sessionManagement</span><span style="color:#89DDFF;">()</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">sessionCreationPolicy</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">SessionCreationPolicy</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">STATELESS</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;">  </span><span style="color:#676E95;font-style:italic;">// 无状态</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">// 拦截规则配置(对不需要拦截的路径进行放行)</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">and</span><span style="color:#89DDFF;">()</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">authorizeRequests</span><span style="color:#89DDFF;">()</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">antMatchers</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">URL_WHITELIST</span><span style="color:#89DDFF;">).</span><span style="color:#82AAFF;">permitAll</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;">  </span><span style="color:#676E95;font-style:italic;">// 白名单 放行</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">anyRequest</span><span style="color:#89DDFF;">().</span><span style="color:#82AAFF;">authenticated</span><span style="color:#89DDFF;">()</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">// 异常处理配置</span></span>
<span class="line"><span style="color:#A6ACCD;">                </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">and</span><span style="color:#89DDFF;">()</span></span>
<span class="line"><span style="color:#A6ACCD;">                </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">exceptionHandling</span><span style="color:#89DDFF;">()</span></span>
<span class="line"><span style="color:#A6ACCD;">                </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">authenticationEntryPoint</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">jwtAuthenticationEntryPoint</span><span style="color:#89DDFF;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">// 自定义过滤器配置</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">and</span><span style="color:#89DDFF;">()</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">addFilter</span><span style="color:#89DDFF;">(</span><span style="color:#82AAFF;">jwtAuthenticationFilter</span><span style="color:#89DDFF;">());</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><h3 id="登录成功处理器" tabindex="-1">登录成功处理器 <a class="header-anchor" href="#登录成功处理器" aria-label="Permalink to &quot;登录成功处理器&quot;">​</a></h3><blockquote><p>目前先不从数据库查找，先自己写，将其注入到上面的SecurityConfig中</p></blockquote><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Component</span></span>
<span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">LoginSuccessHandler</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">implements</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">AuthenticationSuccessHandler</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Override</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">void</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">onAuthenticationSuccess</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">HttpServletRequest</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">httpServletRequest</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#A6ACCD;">                                        </span><span style="color:#C792EA;">HttpServletResponse</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">httpServletResponse</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#A6ACCD;">                                        </span><span style="color:#C792EA;">Authentication</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">authentication</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">throws</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">IOException</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">ServletException</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">// 设定返回结果格式</span></span>
<span class="line"><span style="color:#A6ACCD;">        httpServletResponse</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setContentType</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">application/json;charset=UTF-8</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">ServletOutputStream</span><span style="color:#A6ACCD;"> outputStream </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> httpServletResponse</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getOutputStream</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#89DDFF;">		</span><span style="color:#676E95;font-style:italic;">// 根据用户名生成token</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> username</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">user</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> token </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> JwtUtils</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">genJwtToken</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">username</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#89DDFF;">		</span><span style="color:#676E95;font-style:italic;">// 使用hutool工具转JSON</span></span>
<span class="line"><span style="color:#A6ACCD;">        outputStream</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">write</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">JSONUtil</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">toJsonStr</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">R</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">ok</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">登录成功</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">                                              </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">put</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">authorization</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;">token</span><span style="color:#89DDFF;">)).</span><span style="color:#82AAFF;">getBytes</span><span style="color:#89DDFF;">());</span></span>
<span class="line"><span style="color:#A6ACCD;">        outputStream</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">flush</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">        outputStream</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">close</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><h3 id="登录失败处理器" tabindex="-1">登录失败处理器 <a class="header-anchor" href="#登录失败处理器" aria-label="Permalink to &quot;登录失败处理器&quot;">​</a></h3><blockquote><p>和上面的一样，此处已经完整，后面无需修改</p></blockquote><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Component</span></span>
<span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">LoginFailureHandler</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">implements</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">AuthenticationFailureHandler</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Override</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">void</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">onAuthenticationFailure</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">HttpServletRequest</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">httpServletRequest</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#A6ACCD;">                                        </span><span style="color:#C792EA;">HttpServletResponse</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">httpServletResponse</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#A6ACCD;">                                        </span><span style="color:#C792EA;">AuthenticationException</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">e</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">throws</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">IOException</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">ServletException</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">        httpServletResponse</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setContentType</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">application/json;charset=UTF-8</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">ServletOutputStream</span><span style="color:#A6ACCD;"> outputStream </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> httpServletResponse</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getOutputStream</span><span style="color:#89DDFF;">();</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> message</span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;">e</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getMessage</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">e </span><span style="color:#89DDFF;">instanceof</span><span style="color:#A6ACCD;"> BadCredentialsException</span><span style="color:#89DDFF;">){</span></span>
<span class="line"><span style="color:#A6ACCD;">            message</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">用户名或者密码错误！</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">        outputStream</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">write</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">JSONUtil</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">toJsonStr</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">R</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">error</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">message</span><span style="color:#89DDFF;">)).</span><span style="color:#82AAFF;">getBytes</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">UTF-8</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">));</span></span>
<span class="line"><span style="color:#A6ACCD;">        outputStream</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">flush</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">        outputStream</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">close</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><h3 id="登录处理器" tabindex="-1">登录处理器 <a class="header-anchor" href="#登录处理器" aria-label="Permalink to &quot;登录处理器&quot;">​</a></h3><blockquote><p>需要重写UserDetailService进行查询数据库</p></blockquote><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">interface</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">SysUserService</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">extends</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">IService</span><span style="color:#89DDFF;">&lt;</span><span style="color:#C792EA;">SysUser</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">SysUser</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">getByUsername</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">username</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Service</span></span>
<span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">SysUserServiceImpl</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">extends</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">ServiceImpl</span><span style="color:#89DDFF;">&lt;</span><span style="color:#C792EA;">SysUserMapper</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">SysUser</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">implements</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">SysUserService</span><span style="color:#89DDFF;">{</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Override</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">SysUser</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">getByUsername</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">username</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">getOne</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;font-style:italic;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">QueryWrapper</span><span style="color:#89DDFF;">&lt;</span><span style="color:#C792EA;">SysUser</span><span style="color:#89DDFF;">&gt;().</span><span style="color:#82AAFF;">eq</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">username</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;">username</span><span style="color:#89DDFF;">));</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Service</span></span>
<span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">MyUserDetailsServiceImpl</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">implements</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">UserDetailsService</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Autowired</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">SysUserService</span><span style="color:#A6ACCD;"> sysUserService</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Override</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">UserDetails</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">loadUserByUsername</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">username</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">throws</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">UsernameNotFoundException</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">// 通过数据库查询</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">SysUser</span><span style="color:#A6ACCD;"> sysUser</span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;">sysUserService</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getByUsername</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">username</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">sysUser</span><span style="color:#89DDFF;">==null){</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;font-style:italic;">throw</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">UsernameNotFoundException</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">用户名或者密码错误！</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">}</span><span style="color:#89DDFF;font-style:italic;">else</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">1</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">equals</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">sysUser</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getStatus</span><span style="color:#89DDFF;">())){</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;font-style:italic;">throw</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">UserCountLockException</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">该用户账号被封禁，具体请联系管理员！</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">// 返回结果</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">User</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">sysUser</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getUsername</span><span style="color:#89DDFF;">(),</span></span>
<span class="line"><span style="color:#A6ACCD;">                        sysUser</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getPassword</span><span style="color:#89DDFF;">(),</span></span>
<span class="line"><span style="color:#A6ACCD;">                        </span><span style="color:#82AAFF;">getUserAuthority</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">sysUser</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getId</span><span style="color:#89DDFF;">()));</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Configuration</span></span>
<span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">EnableWebSecurity</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">// 开启Security</span></span>
<span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">EnableGlobalMethodSecurity</span><span style="color:#89DDFF;">(</span><span style="color:#FFCB6B;">prePostEnabled</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">true)</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">// 注解使用</span></span>
<span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">SecurityConfig</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">extends</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">WebSecurityConfigurerAdapter</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Autowired</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">LoginSuccessHandler</span><span style="color:#A6ACCD;"> loginSuccessHandler</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Autowired</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">LoginFailureHandler</span><span style="color:#A6ACCD;"> loginFailureHandler</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Autowired</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">JwtLogoutSuccessHandler</span><span style="color:#A6ACCD;"> jwtLogoutSuccessHandler</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Autowired</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">JwtAuthenticationEntryPoint</span><span style="color:#A6ACCD;"> jwtAuthenticationEntryPoint</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Autowired</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">MyUserDetailsServiceImpl</span><span style="color:#A6ACCD;"> myUserDetailsService</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">final</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> URL_WHITELIST</span><span style="color:#89DDFF;">[]</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">={</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/login</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/logout</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/captcha</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/password</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/image/**</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/test/**</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Bean</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">JwtAuthenticationFilter</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">jwtAuthenticationFilter</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">throws</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Exception</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">JwtAuthenticationFilter</span><span style="color:#89DDFF;">(</span><span style="color:#82AAFF;">authenticationManager</span><span style="color:#89DDFF;">());</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Bean</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">BCryptPasswordEncoder</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">bCryptPasswordEncoder</span><span style="color:#89DDFF;">(){</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">BCryptPasswordEncoder</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">	</span><span style="color:#676E95;font-style:italic;">// 将自己写的userDetailService注册</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Override</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">protected</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">void</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">configure</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">AuthenticationManagerBuilder</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">auth</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">throws</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Exception</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">        auth</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">userDetailsService</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">myUserDetailsService</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Override</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">protected</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">void</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">configure</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">HttpSecurity</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">http</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">throws</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Exception</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">// 开启跨域 以及csrf攻击 关闭</span></span>
<span class="line"><span style="color:#A6ACCD;">        http</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">cors</span><span style="color:#89DDFF;">()</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">and</span><span style="color:#89DDFF;">()</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">csrf</span><span style="color:#89DDFF;">()</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">disable</span><span style="color:#89DDFF;">()</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">// 登录登出配置</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">formLogin</span><span style="color:#89DDFF;">()</span></span>
<span class="line"><span style="color:#A6ACCD;">              </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">successHandler</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">loginSuccessHandler</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">              </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">failureHandler</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">loginFailureHandler</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">and</span><span style="color:#89DDFF;">()</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">logout</span><span style="color:#89DDFF;">()</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">logoutSuccessHandler</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">jwtLogoutSuccessHandler</span><span style="color:#89DDFF;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">// session禁用配置</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">and</span><span style="color:#89DDFF;">()</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">sessionManagement</span><span style="color:#89DDFF;">()</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">sessionCreationPolicy</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">SessionCreationPolicy</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">STATELESS</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;">  </span><span style="color:#676E95;font-style:italic;">// 无状态</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">// 拦截规则配置</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">and</span><span style="color:#89DDFF;">()</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">authorizeRequests</span><span style="color:#89DDFF;">()</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">antMatchers</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">URL_WHITELIST</span><span style="color:#89DDFF;">).</span><span style="color:#82AAFF;">permitAll</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;">  </span><span style="color:#676E95;font-style:italic;">// 白名单 放行</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">anyRequest</span><span style="color:#89DDFF;">().</span><span style="color:#82AAFF;">authenticated</span><span style="color:#89DDFF;">()</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">// 异常处理配置</span></span>
<span class="line"><span style="color:#A6ACCD;">                </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">and</span><span style="color:#89DDFF;">()</span></span>
<span class="line"><span style="color:#A6ACCD;">                </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">exceptionHandling</span><span style="color:#89DDFF;">()</span></span>
<span class="line"><span style="color:#A6ACCD;">                </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">authenticationEntryPoint</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">jwtAuthenticationEntryPoint</span><span style="color:#89DDFF;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">// 自定义过滤器配置</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">and</span><span style="color:#89DDFF;">()</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">addFilter</span><span style="color:#89DDFF;">(</span><span style="color:#82AAFF;">jwtAuthenticationFilter</span><span style="color:#89DDFF;">());</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><h3 id="jwt认证过滤器" tabindex="-1">JWT认证过滤器 <a class="header-anchor" href="#jwt认证过滤器" aria-label="Permalink to &quot;JWT认证过滤器&quot;">​</a></h3><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">JwtAuthenticationFilter</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">extends</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">BasicAuthenticationFilter</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Autowired</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">SysUserService</span><span style="color:#A6ACCD;"> sysUserService</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Autowired</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">MyUserDetailsServiceImpl</span><span style="color:#A6ACCD;"> myUserDetailsService</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">final</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> URL_WHITELIST</span><span style="color:#89DDFF;">[]</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">={</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/login</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/logout</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/captcha</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/password</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/image/**</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/test/**</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">JwtAuthenticationFilter</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">AuthenticationManager</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">authenticationManager</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">        super</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">authenticationManager</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Override</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">protected</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">void</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">doFilterInternal</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">HttpServletRequest</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">request</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#A6ACCD;">                                    </span><span style="color:#C792EA;">HttpServletResponse</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">response</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#A6ACCD;">                                    </span><span style="color:#C792EA;">FilterChain</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">chain</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">throws</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">IOException</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">ServletException</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> token </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> request</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getHeader</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">token</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">        System</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">out</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">println</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">请求url:</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">+</span><span style="color:#A6ACCD;">request</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getRequestURI</span><span style="color:#89DDFF;">());</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">// 如果token是空 或者 url在白名单里，则放行</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">// 这边是为了测试</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">StringUtil</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">isEmpty</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">token</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">||</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">ArrayList</span><span style="color:#89DDFF;">&lt;&gt;(</span><span style="color:#A6ACCD;">Arrays</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">asList</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">URL_WHITELIST</span><span style="color:#89DDFF;">))</span></span>
<span class="line"><span style="color:#A6ACCD;">                     </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">contains</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">request</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getRequestURI</span><span style="color:#89DDFF;">())){</span></span>
<span class="line"><span style="color:#89DDFF;">            </span><span style="color:#676E95;font-style:italic;">// chain.doFilter表示放行</span></span>
<span class="line"><span style="color:#A6ACCD;">            chain</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">doFilter</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">request</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;">response</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">CheckResult</span><span style="color:#A6ACCD;"> checkResult </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> JwtUtils</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">validateJWT</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">token</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#89DDFF;">(!</span><span style="color:#A6ACCD;">checkResult</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">isSuccess</span><span style="color:#89DDFF;">()){</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;font-style:italic;">switch</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">checkResult</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getErrCode</span><span style="color:#89DDFF;">()){</span></span>
<span class="line"><span style="color:#A6ACCD;">              </span><span style="color:#89DDFF;font-style:italic;">case</span><span style="color:#A6ACCD;"> JwtConstant</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">JWT_ERRCODE_NULL</span><span style="color:#89DDFF;font-style:italic;">:throw</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">JwtException</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">Token不存在</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">              </span><span style="color:#89DDFF;font-style:italic;">case</span><span style="color:#A6ACCD;"> JwtConstant</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">JWT_ERRCODE_FAIL</span><span style="color:#89DDFF;font-style:italic;">:throw</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">JwtException</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">Token验证不通过</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">              </span><span style="color:#89DDFF;font-style:italic;">case</span><span style="color:#A6ACCD;"> JwtConstant</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">JWT_ERRCODE_EXPIRE</span><span style="color:#89DDFF;font-style:italic;">:throw</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">JwtException</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">Token过期</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">// 获取token信息</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">Claims</span><span style="color:#A6ACCD;"> claims </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> JwtUtils</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">parseJWT</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">token</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> username </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> claims</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getSubject</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">// 查询数据库</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">SysUser</span><span style="color:#A6ACCD;"> sysUser </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> sysUserService</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getByUsername</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">username</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#89DDFF;">		</span><span style="color:#676E95;font-style:italic;">// 将获取到的信息放到security上下文中</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">UsernamePasswordAuthenticationToken</span><span style="color:#A6ACCD;"> usernamePasswordAuthenticationToken</span><span style="color:#89DDFF;">=</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;font-style:italic;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">UsernamePasswordAuthenticationToken</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">username</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">                                                    </span><span style="color:#89DDFF;">null,</span><span style="color:#A6ACCD;">                                                         myUserDetailsService</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getUserAuthority</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">sysUser</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getId</span><span style="color:#89DDFF;">()));</span></span>
<span class="line"><span style="color:#A6ACCD;">        SecurityContextHolder</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getContext</span><span style="color:#89DDFF;">()</span></span>
<span class="line"><span style="color:#A6ACCD;">                             </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setAuthentication</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">usernamePasswordAuthenticationToken</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">        chain</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">doFilter</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">request</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;">response</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><h3 id="jwt认证失败处理" tabindex="-1">JWT认证失败处理 <a class="header-anchor" href="#jwt认证失败处理" aria-label="Permalink to &quot;JWT认证失败处理&quot;">​</a></h3><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Component</span></span>
<span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">JwtAuthenticationEntryPoint</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">implements</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">AuthenticationEntryPoint</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Override</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">void</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">commence</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">HttpServletRequest</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">httpServletRequest</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#A6ACCD;">                         </span><span style="color:#C792EA;">HttpServletResponse</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">httpServletResponse</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#A6ACCD;">                         </span><span style="color:#C792EA;">AuthenticationException</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">e</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">throws</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">IOException</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">ServletException</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">        httpServletResponse</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setContentType</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">application/json;charset=UTF-8</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">ServletOutputStream</span><span style="color:#A6ACCD;"> outputStream </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> httpServletResponse</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getOutputStream</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">        outputStream</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">write</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">JSONUtil</span><span style="color:#89DDFF;">.</span></span>
<span class="line"><span style="color:#A6ACCD;">                           </span><span style="color:#82AAFF;">toJsonStr</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">R</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">error</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">HttpServletResponse</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">SC_UNAUTHORIZED</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">                                                      </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">认证失败，请登录！</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">)).</span><span style="color:#82AAFF;">getBytes</span><span style="color:#89DDFF;">());</span></span>
<span class="line"><span style="color:#A6ACCD;">        outputStream</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">flush</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">        outputStream</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">close</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><h3 id="退出登录处理" tabindex="-1">退出登录处理 <a class="header-anchor" href="#退出登录处理" aria-label="Permalink to &quot;退出登录处理&quot;">​</a></h3><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Component</span></span>
<span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">JwtLogoutSuccessHandler</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">implements</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">LogoutSuccessHandler</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Override</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">void</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">onLogoutSuccess</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">HttpServletRequest</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">httpServletRequest</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#A6ACCD;">                                </span><span style="color:#C792EA;">HttpServletResponse</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">httpServletResponse</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#A6ACCD;">                                </span><span style="color:#C792EA;">Authentication</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">authentication</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">throws</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">IOException</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">ServletException</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">        httpServletResponse</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setContentType</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">application/json;charset=UTF-8</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">ServletOutputStream</span><span style="color:#A6ACCD;"> outputStream </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> httpServletResponse</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getOutputStream</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">        outputStream</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">write</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">JSONUtil</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">toJsonStr</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">R</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">ok</span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">登出成功</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">)).</span><span style="color:#82AAFF;">getBytes</span><span style="color:#89DDFF;">());</span></span>
<span class="line"><span style="color:#A6ACCD;">        outputStream</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">flush</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">        outputStream</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">close</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><h2 id="实体类-1" tabindex="-1">实体类 <a class="header-anchor" href="#实体类-1" aria-label="Permalink to &quot;实体类&quot;">​</a></h2><h3 id="基础实体类" tabindex="-1">基础实体类 <a class="header-anchor" href="#基础实体类" aria-label="Permalink to &quot;基础实体类&quot;">​</a></h3><div class="language-java"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">Data</span></span>
<span class="line"><span style="color:#C792EA;">public</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">BaseEntity</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">implements</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">Serializable</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">TableId</span><span style="color:#89DDFF;">(</span><span style="color:#FFCB6B;">value</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">id</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">type</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> IdType</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">AUTO</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Long</span><span style="color:#A6ACCD;"> id</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 创建日期</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">JsonFormat</span><span style="color:#89DDFF;">(</span><span style="color:#FFCB6B;">pattern</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">yyyy-MM-dd HH:mm:ss</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Date</span><span style="color:#A6ACCD;"> createTime</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 更新日期</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">@</span><span style="color:#C792EA;">JsonFormat</span><span style="color:#89DDFF;">(</span><span style="color:#FFCB6B;">pattern</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">yyyy-MM-dd HH:mm:ss</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">Date</span><span style="color:#A6ACCD;"> updateTime</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 备注</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">private</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">String</span><span style="color:#A6ACCD;"> remark</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div></div></div></main><footer class="VPDocFooter" data-v-6b87e69f data-v-37656e44><!--[--><!--]--><!----><nav class="prev-next" data-v-37656e44><div class="pager" data-v-37656e44><a class="pager-link prev" href="/notebook/4%E3%80%81%E5%BE%AE%E6%9C%8D%E5%8A%A1/SpringSecurity/%E5%9F%BA%E7%A1%80%E7%AF%87.html" data-v-37656e44><span class="desc" data-v-37656e44>Previous page</span><span class="title" data-v-37656e44>SpringSecurity基础篇</span></a></div><div class="pager" data-v-37656e44><a class="pager-link next" href="/notebook/4%E3%80%81%E5%BE%AE%E6%9C%8D%E5%8A%A1/SpringSecurity/%E9%AB%98%E7%BA%A7%E7%AF%87.html" data-v-37656e44><span class="desc" data-v-37656e44>Next page</span><span class="title" data-v-37656e44>SpringSecurity高级篇</span></a></div></nav></footer><!--[--><!--]--></div></div></div><!--[--><!--]--></div></div><!----><!--[--><!--]--></div></div>
    <script>window.__VP_HASH_MAP__=JSON.parse("{\"2、数据库_mysql_mysql面试_基础.md\":\"40da680a\",\"1、学前端_5、小程序_小程序项目.md\":\"60a1629b\",\"1、学前端_4、node_知识篇.md\":\"a7fb500e\",\"1、学前端_2、js_ts_es6 进阶.md\":\"6d07ba10\",\"1、学前端_3、vue_vue3_vue3进阶.md\":\"7ac622b4\",\"5、运维_jenkins.md\":\"929081f8\",\"1、学前端_2、js_ts_typescript.md\":\"875a4aa4\",\"2、数据库_mysql_mysql核心_设计.md\":\"7faf46d1\",\"2、数据库_mysql_mysql核心_基础.md\":\"d8e97f3e\",\"1、学前端_1、html_css_html基础.md\":\"7584d076\",\"1、学前端_5、专题篇_问题篇.md\":\"e893aaa2\",\"2、数据库_mysql_mysql面试_进阶.md\":\"f934806d\",\"3、springboot_运维_原理.md\":\"f4a39db6\",\"2、数据库_influxdb.md\":\"6e1711e1\",\"3、springboot_新特性.md\":\"cdf3e307\",\"mybatis_mybatisplus_jpa.md\":\"8e41681b\",\"1、学前端_5、小程序_小程序优化.md\":\"a2185198\",\"2、数据库_redis_redis基础.md\":\"856df0e0\",\"linux_实用脚本.md\":\"f2299dd5\",\"4、微服务_必备_分布式基础.md\":\"d49863d5\",\"2、数据库_redis_redis优化.md\":\"e66ae32f\",\"4、微服务_springsecurity_进阶篇.md\":\"235a8e9e\",\"5、运维_chatgpt.md\":\"10db3823\",\"2、数据库_mysql_分库分表.md\":\"e1c8a095\",\"start.md\":\"9bc1ff8d\",\"5、运维_github.md\":\"2ec6c735\",\"java学前端_css.md\":\"f11b47f0\",\"1、学前端_5、专题篇_知识篇.md\":\"a463ed8d\",\"linux_软件部署.md\":\"d6722925\",\"2、数据库_neo4j.md\":\"97ad22ac\",\"team.md\":\"ce467a6a\",\"nginx_实战篇.md\":\"7785486e\",\"index.md\":\"8c3ec167\",\"计算机基础_计算机网络_网络基础.md\":\"7a54a85d\",\"1、学前端_4、node_进阶篇.md\":\"60f6db69\",\"java_java集合.md\":\"a049b313\",\"1、学前端_3、vue_vue3_vue3高级.md\":\"614d1516\",\"1、学前端_5、小程序_微信小程序.md\":\"9a4be771\",\"5、运维_netty.md\":\"12ca0278\",\"2、数据库_mysql_mysql核心_运维.md\":\"83f97c16\",\"idea_vs code.md\":\"afdcb593\",\"java学前端_vue3_组件.md\":\"1086884e\",\"idea_chrome.md\":\"4a32afbc\",\"云原生_k8s.md\":\"db58e65a\",\"2、数据库_mysql_mysql核心_进阶.md\":\"61d16dff\",\"ssm_springbatch.md\":\"f799ab4a\",\"三高_分布式.md\":\"db1b8a1b\",\"2、数据库_elasticsearch_1、es基础.md\":\"04d17448\",\"linux_linux基础.md\":\"4b0bf394\",\"idea_idea插件.md\":\"fa86e45a\",\"可视化 _ 监控_可视化大屏.md\":\"004553bd\",\"2、数据库_mongodb_整合.md\":\"3c47d7f4\",\"4、微服务_springsecurity_基础篇.md\":\"534a3401\",\"4、微服务_进阶.md\":\"69095c58\",\"计算机基础_计算机基础_操作系统.md\":\"0f75d113\",\"可视化 _ 监控_zabbix.md\":\"71f2270e\",\"nginx_基础篇.md\":\"c7d8bb50\",\"1、学前端_4、node_项目实战.md\":\"bc5065b8\",\"2、数据库_redis_redis原理.md\":\"5cedf685\",\"可视化 _ 监控_监控基础.md\":\"ac56ce4d\",\"三高_高并发.md\":\"ea9ffc99\",\"2、数据库_redis_redis高级.md\":\"1d5872f6\",\"1、学前端_4、node_基础篇.md\":\"581cc13a\",\"2、数据库_mongodb_基础.md\":\"fb7a0a29\",\"idea_idea基础.md\":\"6f2f9638\",\"4、微服务_必备_sentinel.md\":\"2edfbf6c\",\"2、数据库_elasticsearch_3、es高级.md\":\"ef146606\",\"1、学前端_3、vue_vue3_vue3新语法.md\":\"8afd5409\",\"消息中间件_canal.md\":\"3949163c\",\"ssm_maven.md\":\"2c5e12ed\",\"4、微服务_springsecurity_高级篇.md\":\"882d3ff3\",\"linux_linux进阶.md\":\"188ef7b4\",\"计算机基础_设计模式_uml.md\":\"634ba256\",\"计算机基础_算法_leetcode.md\":\"77162fb9\",\"项目实战_小兔鲜_进阶篇1.md\":\"17c52c81\",\"1、学前端_2、js_ts_es6 基础.md\":\"fda3f18b\",\"项目实战_小兔鲜_进阶篇2.md\":\"a0f23006\",\"软件测试_测试基础.md\":\"8c1060cd\",\"2、数据库_redis_本地缓存.md\":\"00617fe6\",\"nginx_面试篇.md\":\"e3fb373a\",\"mybatis_mybatisplus_mybatis.md\":\"9239e0ad\",\"linux_shell.md\":\"ae53d83b\",\"2、数据库_mysql_mysql核心_优化.md\":\"36230425\",\"项目实战_项目推荐.md\":\"f9d97630\",\"mybatis_mybatisplus_mybatisplus.md\":\"0030fd35\",\"项目实战_百度地图_进阶篇.md\":\"c8b93267\",\"三高_高可用.md\":\"323840c5\",\"java_java新特性.md\":\"22abf56d\",\"软件测试_压力测试.md\":\"9ab44440\",\"java学前端_html_js.md\":\"e0fcd240\",\"2、数据库_redis_redis实战.md\":\"d6daeeab\",\"nginx_进阶篇.md\":\"e6b63195\",\"三高_秒杀.md\":\"3878bb64\",\"5、运维_git.md\":\"0264925c\",\"java_java进阶.md\":\"e79cb5b4\",\"并发 _ 多线程_基础篇.md\":\"7adbfac5\",\"项目实战_百度地图_基础篇.md\":\"8afa5954\",\"java学前端_react.md\":\"3ec827dd\",\"1、学前端_1、html_css_css基础.md\":\"01b56712\",\"项目实战_小兔鲜_基础篇.md\":\"646f5df5\",\"1、学前端_2、js_ts_js 基础.md\":\"cb13e36f\",\"可视化 _ 监控_监控进阶.md\":\"0cdbc292\",\"计算机基础_设计模式_基础篇.md\":\"51617287\",\"计算机基础_数据结构_基础篇.md\":\"b2bfd8d4\",\"项目实战_苍穹外卖_进阶篇.md\":\"48415e41\",\"ssm_spring.md\":\"ab514659\",\"消息中间件_rabbitmq.md\":\"45b1eb28\",\"1、学前端_1、html_css_网页进阶.md\":\"db998248\",\"消息中间件_kafka.md\":\"b747dabf\",\"云原生_docker.md\":\"983c7ba7\",\"4、微服务_必备_分布式锁.md\":\"5af1cf8d\",\"消息中间件_rocketmq.md\":\"d441da85\",\"项目实战_黑马头条_基础篇.md\":\"b05af3a6\",\"ssm_springmvc.md\":\"81b9714f\",\"项目实战_支付.md\":\"1d7407dd\",\"项目实战_黑马头条_进阶篇2.md\":\"bff0015b\",\"项目实战_黑马头条_进阶篇.md\":\"19f18388\",\"java学前端_vue2_组件.md\":\"58c6b1df\",\"3、springboot_基础篇.md\":\"529c66f4\",\"3、springboot_应用篇.md\":\"8b92aa61\",\"项目实战_黑马头条_高级篇.md\":\"227c08c1\",\"1、学前端_5、小程序_uniapp.md\":\"71a282b4\",\"项目实战_云尚办公_基础篇.md\":\"1fe188ba\",\"并发 _ 多线程_并发完善.md\":\"26619c46\",\"1、学前端_2、js_ts_js 进阶.md\":\"657dfb8f\",\"java_java高级.md\":\"23782d1a\",\"java_java基础.md\":\"86d67c77\"}");window.__VP_SITE_DATA__=JSON.parse("{\"lang\":\"en-US\",\"dir\":\"ltr\",\"title\":\"VitePress\",\"description\":\"A VitePress site\",\"base\":\"/notebook/\",\"head\":[],\"appearance\":true,\"themeConfig\":{\"algolia\":{\"appId\":\"DW7O63I9IR\",\"apiKey\":\"f8ed758cdb288a8b06542bc35923c1a1\",\"indexName\":\"notebook\"},\"sidebar\":[{\"text\":\"Java\",\"collapsed\":true,\"items\":[{\"text\":\"Java基础\",\"link\":\"/Java/Java基础\"},{\"text\":\"Java新特性\",\"link\":\"/Java/Java新特性\"},{\"text\":\"Java进阶\",\"link\":\"/Java/Java进阶\"},{\"text\":\"Java集合\",\"link\":\"/Java/Java集合\"},{\"text\":\"Java高级\",\"link\":\"/Java/Java高级\"}]},{\"text\":\"Linux\",\"collapsed\":true,\"items\":[{\"text\":\"Linux基础\",\"link\":\"/Linux/Linux基础\"},{\"text\":\"Linux新特性\",\"link\":\"/Linux/Linux进阶\"},{\"text\":\"Shell脚本\",\"link\":\"/Linux/Shell\"},{\"text\":\"实用脚本\",\"link\":\"/Linux/实用脚本\"},{\"text\":\"软件部署\",\"link\":\"/Linux/软件部署\"}]},{\"text\":\"Nginx\",\"collapsed\":true,\"items\":[{\"text\":\"基础篇\",\"link\":\"/Nginx/基础篇\"},{\"text\":\"进阶篇\",\"link\":\"/Nginx/进阶篇\"},{\"text\":\"实战篇\",\"link\":\"/Nginx/实战篇\"},{\"text\":\"面试篇\",\"link\":\"/Nginx/面试篇\"}]},{\"text\":\"SSM\",\"collapsed\":true,\"items\":[{\"text\":\"Maven\",\"link\":\"/SSM/Maven\"},{\"text\":\"Spring\",\"link\":\"/SSM/Spring\"},{\"text\":\"SpringMVC\",\"link\":\"/SSM/SpringMVC\"},{\"text\":\"SpringBatch\",\"link\":\"/SSM/SpringBatch\"}]},{\"text\":\"SpringBoot\",\"collapsed\":true,\"items\":[{\"text\":\"基础篇\",\"link\":\"/3、SpringBoot/基础篇\"},{\"text\":\"应用篇\",\"link\":\"/3、SpringBoot/应用篇\"},{\"text\":\"新特性\",\"link\":\"/3、SpringBoot/新特性\"},{\"text\":\"运维&原理\",\"link\":\"/3、SpringBoot/运维&原理\"}]},{\"text\":\"SpringCloud\",\"collapsed\":true,\"items\":[{\"text\":\"SpringCloud\",\"link\":\"/4、微服务/进阶\"},{\"text\":\"Sentinel\",\"link\":\"/4、微服务/必备/Sentinel\"}]},{\"text\":\"SpringSecurity\",\"collapsed\":true,\"items\":[{\"text\":\"SpringSecurity基础篇\",\"link\":\"/4、微服务/SpringSecurity/基础篇\"},{\"text\":\"SpringSecurity进阶篇\",\"link\":\"/4、微服务/SpringSecurity/进阶篇\"},{\"text\":\"SpringSecurity高级篇\",\"link\":\"/4、微服务/SpringSecurity/高级篇\"}]},{\"text\":\"Mybatis & MybatisPlus\",\"collapsed\":true,\"items\":[{\"text\":\"Mybatis\",\"link\":\"/Mybatis&MybatisPlus/Mybatis\"},{\"text\":\"MybatisPlus\",\"link\":\"/Mybatis&MybatisPlus/MybatisPlus\"},{\"text\":\"JPA\",\"link\":\"/Mybatis&MybatisPlus/JPA\"}]},{\"text\":\"Git & ChatGPT\",\"collapsed\":true,\"items\":[{\"text\":\"Git\",\"link\":\"/5、运维/Git\"},{\"text\":\"Github\",\"link\":\"/5、运维/Github\"},{\"text\":\"ChatGPT\",\"link\":\"/5、运维/ChatGPT\"},{\"text\":\"Jenkins\",\"link\":\"/5、运维/Jenkins\"},{\"text\":\"Netty\",\"link\":\"/5、运维/Netty\"}]},{\"text\":\"数据库\",\"collapsed\":true,\"items\":[{\"text\":\"MySQL\",\"collapsed\":true,\"items\":[{\"text\":\"MySQL基础\",\"link\":\"/2、数据库/MySQL/MySQL核心/基础\"},{\"text\":\"MySQL进阶\",\"link\":\"/2、数据库/MySQL/MySQL核心/进阶\"},{\"text\":\"MySQL优化\",\"link\":\"/2、数据库/MySQL/MySQL核心/优化\"},{\"text\":\"MySQL设计\",\"link\":\"/2、数据库/MySQL/MySQL核心/设计\"},{\"text\":\"MySQL运维\",\"link\":\"/2、数据库/MySQL/MySQL核心/运维\"},{\"text\":\"分库分表\",\"link\":\"/2、数据库/MySQL/分库分表\"}]},{\"text\":\"Redis\",\"collapsed\":true,\"items\":[{\"text\":\"Redis基础\",\"link\":\"/2、数据库/Redis/Redis基础\"},{\"text\":\"Redis优化\",\"link\":\"/2、数据库/Redis/Redis优化\"},{\"text\":\"Redis原理\",\"link\":\"/2、数据库/Redis/Redis原理\"},{\"text\":\"Redis高级\",\"link\":\"/2、数据库/Redis/Redis高级\"},{\"text\":\"Redis实战\",\"link\":\"/2、数据库/Redis/Redis实战\"},{\"text\":\"本地缓存\",\"link\":\"/2、数据库/Redis/本地缓存\"}]},{\"text\":\"MongoDB\",\"collapsed\":true,\"items\":[{\"text\":\"MongoDB基础\",\"link\":\"/2、数据库/MongoDB/基础\"},{\"text\":\"MongoDB进阶\",\"link\":\"/2、数据库/MongoDB/整合\"}]},{\"text\":\"ElasticSearch\",\"collapsed\":true,\"items\":[{\"text\":\"ES基础\",\"link\":\"/2、数据库/ElasticSearch/1、ES基础\"},{\"text\":\"ES高级\",\"link\":\"/2、数据库/ElasticSearch/3、ES高级\"}]},{\"text\":\"InfluxDB\",\"link\":\"/2、数据库/influxdb\"},{\"text\":\"Neo4j\",\"link\":\"/2、数据库/Neo4j\"}]},{\"text\":\"高并发 & 秒杀 & 分布式\",\"collapsed\":true,\"items\":[{\"text\":\"分布式理论\",\"link\":\"/三高/分布式\"},{\"text\":\"分布式锁\",\"link\":\"/4、微服务/必备/分布式锁\"},{\"text\":\"秒杀\",\"link\":\"/三高/秒杀\"},{\"text\":\"高可用\",\"link\":\"/三高/高可用\"},{\"text\":\"高并发\",\"link\":\"/三高/高并发\"}]},{\"text\":\"云原生\",\"collapsed\":true,\"items\":[{\"text\":\"Docker\",\"link\":\"/云原生/Docker\"},{\"text\":\"K8S\",\"link\":\"/云原生/K8S\"}]},{\"text\":\"可视化 & 监控\",\"collapsed\":true,\"items\":[{\"text\":\"监控基础\",\"link\":\"/可视化 & 监控/监控基础\"},{\"text\":\"监控进阶\",\"link\":\"/可视化 & 监控/监控进阶\"},{\"text\":\"可视化大屏\",\"link\":\"/可视化 & 监控/可视化大屏\"},{\"text\":\"Zabbix\",\"link\":\"/可视化 & 监控/Zabbix\"}]},{\"text\":\"学前端\",\"collapsed\":true,\"items\":[{\"text\":\"HTML+CSS\",\"collapsed\":true,\"items\":[{\"text\":\"HTML基础\",\"link\":\"/1、学前端/1、HTML+CSS/HTML基础\"},{\"text\":\"CSS基础\",\"link\":\"/1、学前端/1、HTML+CSS/CSS基础\"},{\"text\":\"网页进阶\",\"link\":\"/1、学前端/1、HTML+CSS/网页进阶\"}]},{\"text\":\"JS+TS\",\"collapsed\":true,\"items\":[{\"text\":\"JS基础\",\"link\":\"/1、学前端/2、JS+TS/JS 基础\"},{\"text\":\"JS进阶\",\"link\":\"/1、学前端/2、JS+TS/JS 进阶\"},{\"text\":\"ES6基础\",\"link\":\"/1、学前端/2、JS+TS/ES6 基础\"},{\"text\":\"ES6进阶\",\"link\":\"/1、学前端/2、JS+TS/ES6 进阶\"},{\"text\":\"TS基础\",\"link\":\"/1、学前端/2、JS+TS/TypeScript\"}]},{\"text\":\"NodeJS\",\"collapsed\":true,\"items\":[{\"text\":\"Node基础\",\"link\":\"/1、学前端/4、Node/基础篇\"},{\"text\":\"Node进阶\",\"link\":\"/1、学前端/4、Node/进阶篇\"},{\"text\":\"项目实战\",\"link\":\"/1、学前端/4、Node/项目实战\"}]},{\"text\":\"Vue\",\"collapsed\":true,\"items\":[{\"text\":\"Vue3进阶\",\"link\":\"/1、学前端/3、Vue/Vue3/Vue3进阶\"},{\"text\":\"Vue3高级\",\"link\":\"/1、学前端/3、Vue/Vue3/Vue3高级\"},{\"text\":\"Vue3新语法\",\"link\":\"/1、学前端/3、Vue/Vue3/Vue3新语法\"},{\"text\":\"项目实战\",\"link\":\"/1、学前端/3、Vue/Vue2/Vue2项目\"}]},{\"text\":\"小程序\",\"collapsed\":true,\"items\":[{\"text\":\"小程序基础\",\"link\":\"/1、学前端/5、小程序/微信小程序\"},{\"text\":\"小程序优化\",\"link\":\"/1、学前端/5、小程序/小程序优化\"},{\"text\":\"uniapp\",\"link\":\"/1、学前端/5、小程序/uniapp\"},{\"text\":\"项目实战\",\"link\":\"/1、学前端/5、小程序/小程序项目\"}]}]},{\"text\":\"计算机基础\",\"collapsed\":true,\"items\":[{\"text\":\"数据结构\",\"link\":\"/计算机基础/数据结构/基础篇\"},{\"text\":\"操作系统\",\"link\":\"/计算机基础/计算机基础/操作系统\"},{\"text\":\"设计模式\",\"link\":\"/计算机基础/设计模式/基础篇\"},{\"text\":\"计算机网络\",\"link\":\"/计算机基础/计算机网络/网络基础\"},{\"text\":\"UML\",\"link\":\"/计算机基础/设计模式/UML\"},{\"text\":\"LeetCode\",\"link\":\"/计算机基础/算法/LeetCode\"}]},{\"text\":\"项目实战\",\"collapsed\":true,\"items\":[{\"text\":\"云尚办公\",\"collapsed\":true,\"items\":[{\"text\":\"基础篇\",\"link\":\"/项目实战/云尚办公/基础篇\"}]},{\"text\":\"小兔鲜\",\"collapsed\":true,\"items\":[{\"text\":\"基础篇\",\"link\":\"/项目实战/小兔鲜/基础篇\"},{\"text\":\"进阶篇1\",\"link\":\"/项目实战/小兔鲜/进阶篇1\"},{\"text\":\"进阶篇2\",\"link\":\"/项目实战/小兔鲜/进阶篇2\"}]},{\"text\":\"地图\",\"collapsed\":true,\"items\":[{\"text\":\"基础篇\",\"link\":\"/项目实战/百度地图/基础篇\"},{\"text\":\"进阶篇\",\"link\":\"/项目实战/百度地图/进阶篇\"}]},{\"text\":\"苍穹外卖\",\"collapsed\":true,\"items\":[{\"text\":\"进阶篇\",\"link\":\"/项目实战/苍穹外卖/进阶篇\"}]},{\"text\":\"黑马头条\",\"collapsed\":true,\"items\":[{\"text\":\"基础篇\",\"link\":\"/项目实战/黑马头条/基础篇\"},{\"text\":\"进阶篇\",\"link\":\"/项目实战/黑马头条/进阶篇\"},{\"text\":\"进阶篇2\",\"link\":\"/项目实战/黑马头条/进阶篇2\"},{\"text\":\"高级篇\",\"link\":\"/项目实战/黑马头条/高级篇\"}]},{\"text\":\"支付\",\"link\":\"/项目实战/支付\"},{\"text\":\"项目推荐\",\"link\":\"/项目实战/项目推荐\"}]},{\"text\":\"团队成员\",\"link\":\"/team\"}],\"siteTitle\":\"任硕的文档\",\"logo\":\"/Vue.png\",\"nav\":[{\"text\":\"Java学前端\",\"items\":[{\"items\":[{\"text\":\"HTML+JS\",\"link\":\"/Java学前端/HTML+JS\"},{\"text\":\"CSS\",\"link\":\"/Java学前端/CSS\"},{\"text\":\"Vue2+组件\",\"link\":\"/Java学前端/Vue2+组件\"},{\"text\":\"Vue3+组件\",\"link\":\"/Java学前端/Vue3+组件\"},{\"text\":\"React\",\"link\":\"/Java学前端/React\"}]}],\"activeMatch\":\"/Java/\"},{\"text\":\"软件测试\",\"items\":[{\"items\":[{\"text\":\"测试基础\",\"link\":\"/软件测试/测试基础\"},{\"text\":\"压力测试\",\"link\":\"/软件测试/压力测试\"}]}]},{\"text\":\"多线程\",\"items\":[{\"items\":[{\"text\":\"基础篇\",\"link\":\"/并发 & 多线程/基础篇\"},{\"text\":\"进阶篇\",\"link\":\"/并发 & 多线程/并发完善\"}]}]},{\"text\":\"开发工具\",\"items\":[{\"items\":[{\"text\":\"Chrome\",\"link\":\"/IDEA/Chrome\"},{\"text\":\"IDEA基础\",\"link\":\"/IDEA/IDEA基础\"},{\"text\":\"IDEA插件\",\"link\":\"/IDEA/IDEA插件\"},{\"text\":\"VS Code\",\"link\":\"/IDEA/VS Code\"}]}]},{\"text\":\"消息中间件\",\"items\":[{\"items\":[{\"text\":\"RabbitMQ\",\"link\":\"/消息中间件/RabbitMQ\"},{\"text\":\"RocketMQ\",\"link\":\"/消息中间件/RocketMQ\"},{\"text\":\"Kafka\",\"link\":\"/消息中间件/Kafka\"},{\"text\":\"Canal\",\"link\":\"/消息中间件/Canal\"}]}]}],\"socialLinks\":[{\"icon\":\"github\",\"link\":\"https://github.com/renshuo123/renshuo123.github.io\"},{\"icon\":\"twitter\",\"link\":\"#\"},{\"icon\":{\"svg\":\"<svg t=\\\"1676028692954\\\" class=\\\"icon\\\" ...</path></svg>\"},\"link\":\"https://github.com/\"}]},\"locales\":{},\"scrollOffset\":90,\"cleanUrls\":false}");</script>
    
  </body>
</html>